diff options
Diffstat (limited to 'vendor/x11iraf/cdl/doc/cdlref.ms-V1.0')
-rw-r--r-- | vendor/x11iraf/cdl/doc/cdlref.ms-V1.0 | 2297 |
1 files changed, 2297 insertions, 0 deletions
diff --git a/vendor/x11iraf/cdl/doc/cdlref.ms-V1.0 b/vendor/x11iraf/cdl/doc/cdlref.ms-V1.0 new file mode 100644 index 00000000..52f4fafa --- /dev/null +++ b/vendor/x11iraf/cdl/doc/cdlref.ms-V1.0 @@ -0,0 +1,2297 @@ +.RP +.de us +\\$1\l'|0\(ul' +.. +.TL +A Reference Guide for the IRAF Client Display Library (CDL) +.AU +Michael Fitzpatrick +.AI +NOAO/IRAF Group +.sp 0.5 +February 1997 +.sp 0.5 +\fIRevised September 1997\fR + +.AB +The Client Display Library (CDL) is a host interface for C or Fortran +programs allowing them to display images or overlay graphics to display +servers such as \fIXImtool\fR or \fISAOimage / SAOtng\fR. High-level +procedures allow IRAF or FITS images to be displayed simply, other +routines permit access to all other server functions (e.g. cursor and image +readback, frame selection, etc). The library also features a number of +functions for doing image overlay graphics; supported graphics primitives +include numerous point shapes, lines, circles, ellipses, polygons, annular +shapes, and text. +.AE + +.pn 1 +.bp +.ce +.ps +3 +\fBContents\fR +.ps -3 +.sp 2 +1.\h'|0.25i'\fBIntroduction\fP\l'|5.6i.'\0\01 +.sp 0.5 +2.\h'|0.25i'\fBGetting Started\fP\l'|5.6i.'\0\01 +.sp 0.5 +3.\h'|0.25i'\fBServer Connections\fP\l'|5.6i.'\0\02 +.br +\h'|0.25i'3.1.\h'|0.75i'Domain Sockets\l'|5.6i.'\0\02 +.br +\h'|0.25i'3.2.\h'|0.75i'Named FIFO Pipes\l'|5.6i.'\0\03 +.br +\h'|0.25i'3.3.\h'|0.75i'Inet Sockets\l'|5.6i.'\0\03 +.br +\h'|0.25i'3.4.\h'|0.75i'User-Defined Connections\l'|5.6i.'\0\03 +.sp 0.5 +4.\h'|0.25i'\fBImage Display\fP\l'|5.6i.'\0\03 +.br +\h'|0.25i'4.1.\h'|0.75i'Overview of the Display Process\l'|5.6i.'\0\03 +.br +\h'|0.25i'4.2.\h'|0.75i'Displaying IRAF Images\l'|5.6i.'\0\04 +.br +\h'|0.25i'4.3.\h'|0.75i'Displaying FITS Images\l'|5.6i.'\0\04 +.br +\h'|0.25i'4.4.\h'|0.75i'Displaying Raw Pixels\l'|5.6i.'\0\05 +.br +\h'|0.25i'4.5.\h'|0.75i'Frame Selection\l'|5.6i.'\0\05 +.br +\h'|0.25i'4.6.\h'|0.75i'Clearing the Display\l'|5.6i.'\0\05 +.br +\h'|0.25i'4.7.\h'|0.75i'Frame Buffer Selection\l'|5.6i.'\0\05 +.br +\h'|0.5i'4.7.1.\h'|0.9i'Automatic Selection\l'|5.6i.'\0\06 +.br +\h'|0.5i'4.7.2.\h'|0.9i'The Frame Buffer Configuration File\l'|5.6i.'\0\06 +.br +\h'|0.25i'4.8.\h'|0.75i'Image WCS Description\l'|5.6i.'\0\06 +.br +\h'|0.25i'4.9.\h'|0.75i'Image Colormaps\l'|5.6i.'\0\07 +.br +\h'|0.5i'5.2.1.\h'|0.9i'Imtool Color Model\l'|5.6i.'\0\07 +.br +\h'|0.25i'4.10.\h'|0.75i'ZScale Intensity Mapping\l'|5.6i.'\0\08 +.br +\h'|0.25i'4.11.\h'|0.75i'Image Hardcopy\l'|5.6i.'\0\09 +.br +\h'|0.25i'4.12.\h'|0.75i'Image Cursor\l'|5.6i.'\0\09 +.br +\h'|0.5i'4.13.1.\h'|0.9i'Cursor Sampling\l'|5.6i.'\0\09 +.br +\h'|0.25i'4.14.\h'|0.75i'Image Readout\l'|5.6i.'\0\09 +.br +\h'|0.25i'4.15.\h'|0.75i'Subraster I/O\l'|5.6i.'\0\09 +.sp 0.5 +5.\h'|0.25i'\fBGraphics Overlay\fP\l'|5.6i.'\010 +.br +\h'|0.25i'5.1.\h'|0.75i'Marker Coordinates\l'|5.6i.'\010 +.br +\h'|0.5i'5.1.1.\h'|0.9i'Mapping a Previously Displayed Image\l'|5.6i.'\010 +.br +\h'|0.25i'5.2.\h'|0.75i'Marker Colors\l'|5.6i.'\010 +.br +\h'|0.25i'5.3.\h'|0.75i'Marker Types\l'|5.6i.'\010 +.br +\h'|0.5i'5.3.1.\h'|0.9i'Point\l'|5.6i.'\011 +.br +\h'|0.5i'5.3.2.\h'|0.9i'Line\l'|5.6i.'\011 +.br +\h'|0.5i'5.3.3.\h'|0.9i'Box\l'|5.6i.'\011 +.br +\h'|0.5i'5.3.4.\h'|0.9i'Circle\l'|5.6i.'\011 +.br +\h'|0.5i'5.3.5.\h'|0.9i'Polyline\l'|5.6i.'\012 +.br +\h'|0.5i'5.3.6.\h'|0.9i'Polygon\l'|5.6i.'\012 +.br +\h'|0.5i'5.3.7.\h'|0.9i'Ellipse\l'|5.6i.'\012 +.br +\h'|0.5i'5.3.8.\h'|0.9i'Circular Annuli\l'|5.6i.'\012 +.br +\h'|0.5i'5.3.9.\h'|0.9i'Elliptical Annuli\l'|5.6i.'\012 +.br +\h'|0.5i'5.3.10.\h'|0.9i'Text\l'|5.6i.'\012 +.br +\h'|0.5i'5.4.\h'|0.9i'Text Fonts\l'|5.6i.'\013 +.br +\h'|0.5i'5.5.1.\h'|0.9i'In-line Font Changes\l'|5.6i.'\013 +.br +\h'|0.25i'5.5.\h'|0.75i'Deleting Markers\l'|5.6i.'\013 +.br +\h'|0.5i'5.5.1.\h'|0.9i'Individual Markers\l'|5.6i.'\013 +.br +\h'|0.5i'5.5.2.\h'|0.9i'The Entire Overlay\l'|5.6i.'\014 +.br +\h'|0.25i'5.6.\h'|0.75i'Redrawing the Overlay\l'|5.6i.'\014 +.sp 0.5 +6.\h'|0.25i'\fBFortran Language Binding Notes\fP\l'|5.6i.'\014 +.sp 0.5 +7.\h'|0.25i'\fBSPP Language Binding Notes\fP\l'|5.6i.'\014 +.sp 0.5 +8.\h'|0.25i'\fBIIS Protocol Description\fP\l'|5.6i.'\015 +.sp 0.5 +9.\h'|0.25i'\fBC Interface Summary\fP\l'|5.6i.'\017 +.sp 0.5 +10.\h'|0.25i'\fBC Example Tasks\fP\l'|5.6i.'\019 +.br +\h'|0.25i'10.1.\h'|0.75i'Display Example\l'|5.6i.'\019 +.br +\h'|0.25i'10.2.\h'|0.75i'Interactive Graphics Overlay Example\l'|5.6i.'\022 +.br +\h'|0.25i'10.3.\h'|0.75i'Image Mosaic Example\l'|5.6i.'\026 +.sp 0.5 +11.\h'|0.25i'\fBFortran Interface Summary\fP\l'|5.6i.'\028 +.sp 0.5 +12.\h'|0.25i'\fBFortran Example Tasks\fP\l'|5.6i.'\030 +.br +\h'|0.25i'12.1.\h'|0.75i'Display Example\l'|5.6i.'\030 +.br +\h'|0.25i'12.2.\h'|0.75i'Interactive Graphics Overlay Example\l'|5.6i.'\031 +.sp 0.5 +13.\h'|0.25i'\fBSPP Interface Summary\fP\l'|5.6i.'\033 +.pn 1 + +.NH +Introduction +.LP + For more than a decade IRAF has used a \fIdisplay server\fR as the +primary means for image display. IRAF client tasks connect to the server +and send or read data using a modification of the IIS Model 70 protocol, +originally through named fifo pipes but more recently using unix domain +or inet sockets. The advantage to this approach was that IRAF client tasks +could make use of the image display functionality without duplicating +the code needed for actually displaying the image. The longtime disadvantage +was that the IIS protocol used was arcane and undocumented and therefore +largely unavailable to applications outside of the IRAF project. The +Client Display Library (CDL) provides a public C and Fortran interface for +displaying images and overlay graphics that is independent of the underlying +protocol used. +.LP + Unlike the interface used by IRAF applications, the CDL is meant to +provide an easy-to-use, fully featured interface for applications that can +be easily evolved for future display servers, communications schemes, or +display functionality. Indeed, the CDL is independent of IRAF itself (as +are the display servers) so display tasks can be written for any discipline +or application. +.LP + While this guide assumes programs are written in C, Fortran programmers +should find the translation straightforward by referring to the Fortran +interface summary. The package source files include example tasks as does +this guide; users with problems, questions, or bug reports are encouraged to +contact \fIiraf@noao.edu\fR. A small code sample demonstrating the problem +would be very helpful in finding a solution to any reported problems. + +.NH +Getting Started +.LP + All C programs must include the header file \fB"cdl.h"\fR in order +to get package definitions for constants such as colors and structure +definitions used. The Fortran interface does not \fIrequire\fR anything +similar, however for fortran compilers which support an \f(CWinclude\fR +directive a \fBcdlftn.inc\fR file may be used to define symbolic constants +passed to procedures, this file must be included by each procedure using the +CDL. Fortran programs not using this file must pass in the constants +explicitly, needed values are found throughout this manual. C procedures +which return an integer value will return a positive number to indicate an +error has occured and print an error message, otherwise zero is returned. +.LP + The \fBcdl_open()\fR procedure is used to establish a connection +to the server and initialize the package, it returns a CDL structure pointer +that is passed to other CDL procedures. For C programs this means +a separate pointer may be maintained for each server connection, the Fortran +interface is limited to only one server connection per process since the +pointer is maintained internally. The connection is terminated using the +\fBcdl_close()\fR procedure. Between these two calls may be any combination +of CDL procedure calls for doing image display or overlay graphics. +.LP + For example, the simplest possible program for displaying an IRAF +image would look something like: +.sp 0.5 +.nf + \f(CW#include "cdl.h" + + main (int argc, char *argv[]) + { + CDLPtr cdl = cdl_open ((char *)0); + cdl_displayIRAF (cdl, argv[1], 1, 1, 1, 1); + cdl_close (cdl); + }\fR +.fi +.sp 0.5 +.LP +This program displays band one of an image named on the command line to the +server in frame one using the default 512x512 frame buffer, zscaling the +pixels to 8-bit values automatically. No error checking is performed to verify +that a connection was established or that the argument is a valid IRAF image. +Most programs will be more complex than this but it should be clear that +image display from client applications is a now trivial operation. + +.us "Synopsis" +.sp 0.5 +.nf + \f(CW#include "cdl.h"\fR + + \f(CWCDLPtr cdl_open (char *imtdev)\fR + \f(CWvoid cdl_close (CDLPtr cdl)\fR +.fi + +.NH +Server Connections +.LP + The \fBcdl_open()\fR procedure takes a single argument specifying the +type of connection to make to the server, this routine also initializes +the CDL package. If this is a NULL pointer the CDL will attempt to first +connect on a unix domain socket, if that fails the standard IRAF /dev/imt1* +fifo pipes are tried. The syntax for the \fIimtdev\fR argument is as follows: +.sp 0.5 + \f(CW<domain> : <address>\fR +.sp 0.5 +.LP +where <domain> is one of "\fBinet\fR" (internet tcp/ip socket), "\fBunix\fR" +(unix domain socket) or "\fBfifo\fR" (named pipe). The form of the address +depends upon the domain, as illustrated in the examples below. The address +field may contain up to two "%d" fields. If present, the user's UID will be +substituted (e.g. "unix:/tmp/.IMT%d"). The default connection if no imtdev +is specified is "unix:/tmp/.IMT%d", failing that a connection is attempted +on the /dev/imt1[io] named fifo pipes. +.NH 2 +Domain Sockets +.LP + Domain sockets are sockets created on the local host. The connection +is usually faster than an inet socket and comparable to a fifo. If the +socket name is specified with a '%d' field the client can be assured of a +unique socket name for each user allowing multiple clients to be run on the +same host by different users. +.LP +.us "Example" +.sp 0.5 +.nf +\f(CW + /* Connection to a local host using socket domain socket. */ + if ((cdl = cdl_open ("unix:/tmp/.IMT%d")) == NULL) { + fprintf (stderr, "cannot open domain socket connection\\n"); + exit (1); + } \fR +.fi +.NH 2 +Named FIFO Pipes +.LP + This is the traditional approach, and the only one supported by +SAOimage (although recent versions contain support for sockets). Any named +fifo pipe may be used, the syntax for the \fIimtdev\fR string in this case is +.sp 0.5 + \fBfifo:\f(CW<input_fifo>\fB:\f(CW<output_fifo>\fR +.sp 0.5 +.LP +.us "Example" +.sp 0.5 +.nf + \f(CW/* Connection to a local host using named fifo pipes. */ + if ((cdl = cdl_open ("fifo:/dev/imt1i:/dev/imt1o")) == NULL) { + fprintf (stderr, "cannot open fifo pipe connection\\n"); + exit (1); + } \fR +.fi +.NH 2 +Inet Sockets +.LP + Inet sockets are connections between hosts via a tcp/ip socket. +This permits connecting to the server over a remote network connection +anywhere on the Internet. +.LP +.us "Example" +.sp 0.5 +.nf + \f(CW/* Connection to a local host using socket 5137. */ + if ((cdl = cdl_open ("inet:5137")) == NULL) { + fprintf (stderr, "cannot open inet socket connection\\n"); + exit (1); + } + + /* Connection to a remote internet host using socket 5137. */ + if ((cdl = cdl_open ("inet:5137:foo.bar.edu")) == NULL) { + fprintf (stderr, "cannot open inet socket connection\\n"); + exit (1); + } \fR +.fi +.NH 2 +User-Defined Connections +.LP + Since IRAF V2.10.3 client tasks have been able to use an \fBIMTDEV\fR +unix environment variable to set the connection type, the syntax of this +variable is the same as described above. If the \fIcdl_open()\fR procedure +is called with a NULL pointer the IMTDEV environment variable will +automatically be checked. To explicitly use this variable in the client +task the \fIcdl_open()\fR procedure may be called as +e.g. +.sp 0.5 +.nf + \f(CWif ((cdl = cdl_open (getenv("IMTDEV"))) == NULL) { + fprintf (stderr, "cannot open server connection\\n"); + exit (1); + }\fR +.fi +.NH +Image Display +.NH 2 +Overview of the Display Process +.LP + Basic image display is done most easily using the high-level +\fBcdl_displayIRAF()\fR, \fBcdl_displayFITS()\fR and \fBcdl_displayPix()\fR +procedures. These routines automaticaly define an image WCS, clear the +frame, set the frame buffer and center the image in the display. For most +applications these are all that will be needed, but the +\fBcdl_writeSubRaster()\fR procedure can also be used to display an image. +For example, to display one image in a mosaic or other cases where +the task needs low-level access to position the image or write raw pixel +values. +.LP + In these cases it is the responsibility of the client program to +prepare the server for display. The basic steps involed in displaying an +image include +.sp 0.5 +.TS +center; +lB lB +- - +l lI. +Operation CDL Procedure +Selecting the frame cdl_setFrame() +Clear the frame cdl_clearFrame() +Select the frame buffer configuration cdl_selectFB() +Set the frame buffer configuration cdl_setFBConfig() +Scale the image pixels to 201 display values cdl_zscaleImage() +Define the image WCS +Set the image WCS cdl_setWCS() +Compute the raster placement in the frame buffer +Write the pixels to the display cdl_writeSubRaster() +.TE +.sp 0.5 +In cases like a mosaic display obviously clearing the frame will only need +to be done once and a single WCS for the mosaic should be defined. For +simple display the high-level routines handle all of these steps for you, they +are included here as checklist of what must be considered when using the CDL +for low-level display. +.NH 2 +Displaying IRAF Images +.LP + The \fBcdl_displayIRAF()\fR procedure can be used to display an IRAF +OIF format image (i.e. images with a \fI.imh\fR extension) by simply +passing in the image name. Pixel files for the +image must be accessible from the local machine but can be in any directory, +the HDR$ syntax for the imdir is also recognized. Images may be three +dimensional, the +\fIband\fR argument is used to select the image band to be displayed. +The \fIframe\fR and \fIfbconfig\fR arguments select the frame and frame buffer +size respectively, if the \fIzscale\fR flag is greater than zero the image +will automatically be converted to 8-bit values using the zscale mapping +algorithm. The function returns a positive value if the image cannot +be accessed or displayed for any reason, an error message will be printed. +.LP + The \fIcdl_isIRAF()\fR procedure returns a positive value if the +filename argument is recognized as an IRAF image, it does not check whether +the pixel file can be successfully accessed. For simply reading the pixels +from an IRAF image the \fBcdl_readIRAF()\fR procedure may be used. The +function returns a zero value and sets the output pixel array, image +dimensions and pixel size if successful, otherwise the function returns a +positive value. Note that +the output pixel values may need to be scaled before they can be displayed. + +.us "Synopsis" +.nf + \f(CWint cdl_displayIRAF (CDLPtr cdl, char *fname, int band, + int frame, int fbconfig, int zscale)\fR + \f(CWint cdl_isIRAF (char *fname)\fR + \f(CWint cdl_readIRAF (char *fname, int band, uchar **pix, + int *nx, int *ny, int *bitpix)\fR +.fi +.NH 2 +Displaying FITS Images +.LP + The \fBcdl_displayFITS()\fR procedure can be used to display a +\fIsimple\fR FITS image by name. A "simple" FITS file is assumed to be +one containing a single image and having no extensions. Other types of +FITS files may of course be displayed but the client will have to use other +means to import the pixels. FITS image extensions may be supported in a future +release of the CDL. The \fIframe\fR and \fIfbconfig\fR +arguments select the frame and frame buffer size respectively, if the +\fIzscale\fR flag is greater than zero the image will automatically be +converted to 8-bit values using the zscale mapping algorithm. The function +returns a positive value if the image cannot be accessed or displayed for +any reason, an error message will be printed. +.LP + The \fIcdl_isFITS()\fR procedure returns a positive value if the +filename argument is recognized as a simple FITS image. For simply reading +the image pixels the \fBcdl_readFITS()\fR procedure may be used. The +output pixel array, image dimensions and pixel size are returned if +successful otherwise the function returns a positive value. Note that +the returned pixel values may need to be scaled before they can be displayed. + +.us "Synopsis" +.nf + \f(CWint cdl_displayFITS (CDLPtr cdl, char *fname, int frame, + int fbconfig, int zscale)\fR + \f(CWint cdl_isFITS (char *fname)\fR + \f(CWint cdl_readFITS (char *fname, uchar **pix, int *nx, int *ny, + int *bitpix)\fR +.fi +.NH 2 +Displaying Raw Pixels +.LP + The \fBcdl_displayPix()\fR procedure can be used to display an +arbitrary array of pixels of any size. The \fInx\fR and \fIny\fR arguments +are the raster dimensions, and \fIbitpix\fR is the pixel size and has the +same meaning as the FITS BITPIX keyword. The \fIframe\fR and \fIfbconfig\fR +arguments select the frame and frame buffer size respectively, if the +\fIzscale\fR flag is greater than zero the image will automatically be +converted to 8-bit values using the zscale mapping algorithm. + +.us "Synopsis" +.nf + \f(CWint cdl_displayPix (CDLPtr cdl, uchar *pix, int nx, int ny, + int bitpix, int frame, int fbconfig, int zscale)\fR +.fi +.NH 2 +Frame Selection +.LP + Frame selection is normally done as an argument to one of the display +procedures, however frames may be explicitly selected using the +\fBcdl_setFrame()\fR procedure. This allows client programs to essentially +"blink" frames independently, as long as the server supports multiple frames. + +.us "Synopsis" +.nf + \f(CWvoid cdl_getFrame (CDLPtr cdl, int frame)\fR +.fi +.NH 2 +Clearing the Display +.LP + The current display frame may be explicitly cleared using the +\fBcdl_clearFrame()\fR procedure. The frame is also cleared prior to +displaying new images by the procedures \fBcdl_displayPix()\fR, +\fBcdl_displayFITS()\fR, and \fBcdl_displayIRAF()\fR. + +.us "Synopsis" +.nf + \f(CWint cdl_clearFrame (CDLPtr cdl)\fR +.fi +.NH 2 +Frame Buffer Selection +.LP + The default frame buffer used is 512x512, other sizes may be +selected using the \fBcdl_setFBConfig()\fR procedure. To set the frame +buffer size the client passes the frame buffer number as defined in +the frame buffer configuration file (see below) while setting the image +WCS. It is important to note that the frame buffer isn't actually changed +in the server +until a subsequent \fBcdl_setWCS()\fR call, either directly or through +some other procedure which sets the WCS (e.g. one of the display procedures). +.LP + To get the size of the currently defined frame buffer the user +may call the \fBcdl_getFBConfig()\fR procedure. This returns not only +the current configuration number, but the size as well. To get the size +and any arbitrary configuration without actually setting it, the +\fBcdl_lookupFBSize()\fR procedure may be used. Any configuration not actually +defined in the frame buffer configuration file is returned as the default +512x512 size. + +.us "Synopsis" +.nf + \f(CWvoid cdl_setFBConfig (CDLPtr cdl, int configno)\fR + \f(CWvoid cdl_getFBConfig (CDLPtr cdl, int *configno, int *width, + int *height, int *nframes)\fR + \f(CWvoid cdl_lookupFBSize (CDLPtr cdl, int configno, int *width, + int *height, int *nframes)\fR +.fi +.NH 3 +Automatic Selection +.LP + The \fBcdl_selectFB()\fR procedure may be used to select the most +appropriate frame buffer to use for a given image size. If possible a frame +buffer the same size as the image will be used, otherwise one that is +larger will be chosen. Rather than simply selecting the first configuration +larger than the image, the procedure searches the entire configuration file +selecting the one with the least empty space in both dimensions. If the +\fIreset\fR flag is non-zero this frame is set automatically by the +procedure, otherwise the selected dimension is simply returned to the +calling program. In either case the new frame buffer will not take effect +until a new WCS is defined for the frame. + +.us "Synopsis" +.nf + \f(CWvoid cdl_selectFB (CDLPtr cdl, int nx, int ny, int *fb, + int *w, int *h, int *nf, int reset) +. +.NH 3 +The Frame Buffer Configuration File +.LP + The size of the frame buffer is not passed directly to the server +since this is not part of the communications protocol used. Instead, the +frame buffer number is sent as part of the WCS header packet. So that +both the server and client can know that a particular frame buffer number +corresponds to a specific size, a \fIframe buffer configuration file\fR +is used which both the client and server read. +.LP + The default configuration file is /usr/local/lib/imtoolrc, this can +be overridden by defining an \fBIMTOOLRC\fR environment variable naming +the file to be used, or by creating a .imtoolrc file in your home directory. +Since the server must also read the same file, this must be done before +starting both the client and server applications. +.LP +The format of the frame buffer configuration file is +.sp 0.5 + \fIconfigno nframes width height [extra fields]\fP +.sp 0.5 +e.g. +.sp 0.5 + 1 2 512 512 + 2 2 800 800 + 3 1 1024 1024 # comment + : : : : + +At most 128 frame buffer sizes may be defined, each configuration may define +up to 4 frames, configuration numbers need not be sequential but should be +in ascending order. +.NH 2 +Image WCS Description +.LP + The image WCS is defined using the \fBcdl_setWCS()\fR procedure. The +WCS defines a mapping between any linear coordinate system and the image +pixels, for our purposes we will discuss how the WCS is used to map the frame +buffer pixels to image coordinates. It is passed to the server in a string +of the form: +.sp 0.5 + Image_Name_String\\n a b c d tx ty z1 z2 zt +.sp 0.2 +where: +.sp 0.2 + X' = a*X + c*Y + tx + Y' = b*X + d*Y + ty + +The terms \fIa, b, c\fR, and \fId\fR define a rotation of the WCS wrt the pixel +coordinates, the \fItx\fR and \fIty\fR values are translation terms. The +remaining three values define the intensity mapping of the display pixels; +\fIz1\fR is the minimum pixel value used in the transformation, \fIz2\fR is +the maximum value, and \fIzt\fR defines the type of transformation used (0 for +none, 1 for linear, 2 for log10). +.LP + The WCS may be set explicitly by the calling program or a default +appropriate for the image will be set automatically by the high-level +display procedures, otherwise a WCS for the +frame buffer is defined (i.e. returned coordinates are frame buffer coords). +As an example of how the WCS is defined, the default WCS for an image +IMX x IMY pixels in a frame buffer FBX x FBY pixels is defined as +.sp 0.5 +.nf +\f(CW a = 1.0; /* no rotation */ + b = 0.0; + c = 0.0; + d = -1.0; + tx = (IMX / 2) - (FBX / 2) + 1; /* center in FB */ + ty = (FBY / 2) + (IMY / 2); + z1 = z1; /* zscale values */ + z2 = z2; + zt = 1;\fR +.fi + +.us "Synopsis" +.nf + \f(CWint cdl_setWCS (CDLPtr cdl, char *name, char *title, + float a, float b, float c, float d, float tx, float ty, + float z1, float z2, int zt)\fR + \f(CWint cdl_getWCS (CDLPtr cdl, char *name, char *title, + float *a, float *b, float *c, float *d, float *tx, float *ty, + float *z1, float *z2, int *zt)\fR +.fi +.NH 2 +Image Colormaps +.LP + The IIS protocol used does not permit the downloading of user-defined +colormaps, all images are loaded as raw grayscale values according to the +XImtool colormap model used by currently supported servers. All images +containing private colormaps or more than the 201 grayscale values defined +by the Imtool colormap model must either convert the image to 8-bit +grayscale values by calling the CDL zscale procedures (\fBcdl_computeZscale()\fR +and \fBcdl_zscaleImage()\fR) or scale the images in client code with +user LUTs. The CDL zscale procedures scale image to 201 grayscale values +so that they are displayed to the full 8-bit range, user LUT +transformations or user code for converting to grayscale from a private +colormap procedures should do the same. +.NH 3 +Imtool Color Model +.LP + The IMTOOL color model defines at most 201 grayscale values for use in +displaying the image, a set of 16 static colors are also defined for overlay +graphics. Pixel values sent to the server should be already scaled to this +model, i.e. the image pixels should be scaled to the range 1-200, values +above this will either represent the overlay colors or will wrap around to +8-bit values. The CDL zscale procedures will automatically scale +arbitrary pixel values to use this color model, the overlay procedures +assume color values are defined for the static color range 201-217 but any +8-bit value may be used. +.LP + A summary of the color model values is included below: +.TS +center; +lB lB cB cB lB lB +l l c c l l. +Color Description Color Description +0 Background 208 Cyan +1 - 200 Image data 209 Magenta +201 Cursor (white) 210 Coral +202 Background (black) 211 Maroon +203 White 212 Orange +204 Red 213 Khaki +205 Green 214 Orchid +206 Blue 215 Turquoise +207 Yellow 216 Violet +217 Wheat 218-255 undefined +.TE +.NH 2 +ZScale Intensity Mapping +.LP + Since most display servers are only capable of displaying 8-bit pixel +values, images with more than 8-bits per pixel must be scaled prior to +display. For linear transformations this is typically done using a simple +conversion of the image min/max values to the 256 grayscale values, however +this doesn't produce very good results when most pixel values are near one +of the extremes (usually the image min for astronomical images). To solve +this IRAF uses a \fIzscale\fR mapping algorithm where a sampling grid is used +to approximate the image min/max values rather than computing it directly, +a line is then fit to these sample pixels to determine the optimal +transformation to the display values. This is not only more efficient but +maps the most common pixel values to the display range producing a better image. +.LP + The CDL has several routines for doing the same transformation: the +\fIcdl_computeZscale()\fR procedure is used to compute the optimal \fIz1\fR +and \fIz2\fR +values (the min/max used for the zscale transform) for an image of any pixel +size. The \fIbitpix\fR argument is the number of bits-per-pixel for the input +array and has the same meaning as for the FITS \fIBITPIX\fR keyword. To then +transform the image using these values (or user-defined values) the +\fIcdl_zscaleImage()\fR procedure is used. The input pixels are modified by +this procedure but the array is not reallocated to the smaller size needed by +an 8-bit array. The \fBcdl_setSample()\fR and \fBcdl_setSampleLines()\fR +procedures can be used to change the sampling grid and number of sample +points (the default is 600 points on 5 lines). The \fBcdl_setContrast()\fR +procedure can be used to change the default contrast adjustment to the slope +used in the transformation (the default is 0.25). If a value of zero is +given then the minimum and maximum of the intensity sample is used as the +z1/z2 value. +.LP + Each of the CDL display procedures has a \fIzscale\fR flag to +automatically scale the pixels prior to display. Applications wishing to +set their own z1/z2 values will need to call the zscale procedures and +disable this flag. By default cdl_zscaleImage() will use a linear transform, +the \fBcdl_setZTrans()\fR procedure may be used to change this. Acceptable +values are \fBCDL_UNITARY\fR (zero) for a unitary transform, \fBCDL_LINEAR\fR +(one) for a linear transform, or \fBCDL_LOG\fR (two) for a log10 transform. + +.us "Synopsis" +.nf + \f(CWvoid cdl_computeZscale (CDLPtr cdl, uchar *pix, int nx, + int ny, int bitpix, float *z1, float *z2)\fR + \f(CWvoid cdl_zscaleImage (CDLPtr cdl, uchar **pix, int nx, + int ny, int bitpix, float z1, float z2)\fR + + \f(CWvoid cdl_setZTrans (CDLPtr cdl, int ztrans)\fR + \f(CWvoid cdl_getZTrans (CDLPtr cdl, int *ztrans)\fR + \f(CWvoid cdl_setZScale (CDLPtr cdl, float z1, float z2)\fR + \f(CWvoid cdl_getZScale (CDLPtr cdl, float *z1, float *z2)\fR + + \f(CWvoid cdl_setSample (CDLPtr cdl, int nsample)\fR + \f(CWvoid cdl_setSampleLines (CDLPtr cdl, int nlines)\fR + \f(CWvoid cdl_setContrast (CDLPtr cdl, float contrast)\fR + \f(CWvoid cdl_getSample (CDLPtr cdl, int *nsample)\fR + \f(CWvoid cdl_getSampleLines (CDLPtr cdl, int *nlines)\fR + \f(CWvoid cdl_getContrast (CDLPtr cdl, float *contrast)\fR + +.fi +.NH 2 +Image Hardcopy +.LP + While most servers include some hardcopy capability of their own the +CDL provides two procedures for creating hardcopy images from the client +(e.g. for a batch processing application). The client will typically read +back the entire image, frame buffer, of just a subraster and pass those +pixels to the print procedure. Images will be written as Pseudocolor +Postscript (to preserve the overlay marker colors) and may be disposed to +a file using the \fBcdl_printPixToFile()\fR procedure or to any command string +accepting input from \fIstdin\fR (typically just an 'lpr' command) by using +the \fBcdl_printPix()\fR procedure. + +.us "Synopsis" +.nf + \f(CWint cdl_printPix (CDLPtr cdl, char *cmd, uchar *pix, int nx, + int ny, int annotate)\fR + \f(CWint cdl_printPixToFile (CDLPtr cdl, char *fname, uchar *pix, + int nx, int ny, int annotate)\fR +.fi +.NH 2 +Image Cursor +.LP + The image cursor is read using the \fBcdl_readCursor()\fR procedure. +The returned value is the cursor \fI(x,y)\fR position as floating point value +in terms of the currently define image WCS. Note that this position must +be converted to integer if it is to be used in one of the marker procedures. + +.us "Synopsis" +.nf + \f(CWint cdl_readCursor (CDLPtr cdl, int sample, float *x, + float *y, char *key)\fR +.fi +.NH 3 +Cursor Sampling +.LP + If the cdl_readCursor() \fIsample\fR flag is non-zero the \fIlogical +image cursor\fR position is returned immediately, otherwise the display server +will wait for a keystroke before returning the cursor position. The logical +image cursor is the last value set by a \fIcdl_setCursor()\fR call or the last +value returned by a \fIbcdl_readCursor()\fR call. When sampling the cursor +position the keystroke value is undefined. +.NH 2 +Image Readout +.LP + The CDL maintains an internal knowledge of where an image has been +positioned if it was displayed using one of the \fIcdl_display*\fR procedures. +The \fBcdl_readImage()\fR procedure may be used to read back the entire image +pixels from the server ignoring the region of the frame buffer outside of +the image, the \fBcdl_readFrameBuffer()\fR procedure will read back the +contents of the entire frame buffer. The dimensions of the array are returned +in the \fInx\fR and \fIny\fR arguments. + +.us "Synopsis" +.nf + \f(CWint cdl_readImage (CDLPtr cdl, uchar **pix, int *nx, + int *ny)\R + \f(CWint cdl_readFrameBuffer (CDLPtr cdl, uchar **pix, + int *nx, int *ny)\R +.fi +.NH 2 +Subraster I/O +.LP + The \fBcdl_writeSubRaster()\fR procedure is used to write an arbitrary +raster to any location in the display. Similarly the +\fBcdl_readSubRaster()\fR procedure is used to read back an arbitrary raster. +When an image has previously been displayed the subraster position is given +in image coordinates (e.g. when writing a subregion of edited pixels), +otherwise the position is in frame buffer coordinates (e.g. to display +multiple images per frame you should use the cdl_writeSubRaster() call). +See the section on \fIMarker Coordinates\fR for further explanation of the +coordinate systems used. + +.us "Synopsis" +.nf + \f(CWint cdl_writeSubRaster (CDLPtr cdl, int lx, int ly, int nx, + int ny, uchar *pix)\fR + \f(CWint cdl_readSubRaster (CDLPtr cdl, int lx, int ly, int nx, + int ny, uchar **pix)\fR +.fi +.NH +Graphics Overlay +.NH 2 +Marker Coordinates +.LP + All marker positions are assumed to be image pixel coordinates, +although there is no requirement that the position be on the image itself. +When an image WCS is defined (using the CDL display procedures or explicitly) +the origin of the coordinates used shifts from the frame buffer lower-left +to the lower-left of the image as displayed in the frame. Negative +positions are allowed and will either refer to empty pixels if the frame +buffer is larger than the image, or pixels outside the frame buffer +boundaries. Raster I/O requests will be clipped to the frame buffer +endpoints, a request completely outside the frame buffer is an error. +.NH 3 +Mapping a Previously Displayed Image +.LP + Ideally any application wishing to draw markers on an image will have +also displayed that image, however the \fBcdl_mapFrame()\fR procedure may +be used to map the requested frame for marker overlay. It does this by +reading the WCS defined for that frame and assumes an image has been +displayed and centered in the frame buffer, then resets the internal CDL +image position. If no image has been displayed the frame buffer is mapped +directly. This can be used for example to map an empty frame for displaying +just the markers without an image, or for mapping another frame's WCS for +use on the current display. The frame is not changed by the procedure call +however the current WCS \fIis\fR changed. + +.us "Synopsis" +.nf + \f(CWint cdl_mapFrame (CDLPtr cdl, int frame)\fR +.fi +.NH 2 +Marker Colors +.LP + Markers may be drawn using any 8-bit value, in order to use the +static overlay colors the color must be in the range 201-217 (see above for +notes on the XImtool color model). The "\fIcdl.h\fR" include file +for C programs, or the "\fIcdlftn.inc\fR" include for fortran programs, +defines the following symbolic constants for each of the static overlay colors: +.sp 0.5 +.TS +center; +lB l c c lB l. +C_BLACK 202 C_CORAL 210 +C_WHITE 203 C_MAROON 211 +C_RED 204 C_ORANGE 212 +C_GREEN 205 C_KHAKI 213 +C_BLUE 206 C_ORCHID 214 +C_YELLOW 207 C_TURQUOISE 215 +C_CYAN 208 C_VIOLET 216 +C_MAGENTA 209 C_WHEAT 217 +.TE +.NH 2 +Marker Types +.LP + Currently supported marker types include: \fI +.TS +center; +l l l l l. +Point Line Box Polyline Polygon +Circle Circular Annuli Ellipse Elliptical Annuli Text +.TE +.LP + \fRThe "\fIcdl.h\fR" include file for C programs, or the +"\fIcdlftn.inc\fR" include for fortran programs, defines the following +symbolic constants for each of the defined \fIPoint\fR marker types: +.TS +center; +lB r c c lB r. +M_FILL 1 M_CIRCLE 64 +M_POINT 2 M_STAR 128 +M_BOX 4 M_HLINE 256 +M_PLUS 8 M_VLINE 512 +M_CROSS 16 M_HBLINE 1024 +M_DIAMOND 32 M_VBLINE 2048 +.TE +.LP + Point markers are drawn using the \fBcdl_markPoint()\fR procedure, +point types may be logically \fIOR\fR'd to create composite markers, closed +shapes such as a circles, diamonds, or squares may be \fIOR\fR'd with the +M_FILL flag to flood-fill the point with the current overlay color. +.NH 3 +Point +.LP + The \fBcdl_markPoint()\fR procedure is used to mark a specific point +on the image using one of the marker types listed above. The marker is +centered at the coordinates specified by the \fIx\fR and \fIy\fR arguments, +\fItype\fR is an integer flag indicating what kind of marker to draw and +may be a composite type by logically ORing two or more marker types. +\fISize\fR is the width and height of the marker measured in pixel unxits, +and \fIcolor\fR is the color used to draw the marker. If the \fInumber\fR +argument is greater than zero that number will be drawn next to the point +as a label, +creating text labels for point markers can bedone using the +\fIcdl_markPointLabel\fR procedure. +.LP + Most marker names are fairly obvious but several are worth special +mention: The M_DIAMOND, M_CIRCLE and M_BOX marker types may be logically +\fIOR\fRed with the M_FILL flag to produce a filled marker type. Unless +\fIOR\fRd with the M_POINT flag all point markers will leave the center +pixel unchanged. The M_HLINE and M_VLINE markers are most useful in +astronomical applications to mark an individual star, they are horizontal +and vertical lines respectively with a gap in the middle third of the marker +(the M_HBLINE and M_VBLINE are identical but with a width of 3 pixels). +.sp 0.5 +.us "Synopsis" +.nf + \f(CWint cdl_markPoint (CDLPtr cdl, int x, int y, int number, + int size, int type, int color)\fR + \f(CWint cdl_markPoint (CDLPtr cdl, int x, int y, char *label + int size, int type, int color)\fR +.fi +.NH 3 +Line +.LP + The \fBcdl_markLine()\fR procedure is used to draw a line of the +specified color between points (\fIxs,ys\fR) and (\fIxe,ye\fR). +.sp 0.5 +.us "Synopsis" +.nf + \f(CWint cdl_markLine (CDLPtr cdl, int xs, int ys, int xe, int ye, + int color)\fR +.fi +.NH 3 +Box +.LP + The \fBcdl_markBox()\fR procedure is used to draw a box of the +specified color with endpoints specified by (\fIlx,ly\fR) and (\fIux,uy\fR). +If the \fIfill\fR flag is set the box will be filled with the marker color. +.sp 0.5 +.us "Synopsis" +.nf + \f(CWint cdl_markBox (CDLPtr cdl, int lx, int ly, int ux, int uy, + int fill, int color)\fR +.fi +.NH 3 +Circle +.LP + The \fBcdl_markCircle()\fR procedure is used to draw a circle of the +specified color with a center at (\fIx,y\fR) and radius \fIradius\fR. +If the \fIfill\fR flag is set the circle will be filled with the marker color. +.sp 0.5 +.us "Synopsis" +.nf + \f(CWint cdl_markCircle (CDLPtr cdl, int x, int y, int radius, + int fill, int color)\fR +.fi +.NH 3 +Polyline +.LP + The \fBcdl_markPolyline()\fR procedure is used to draw a line +connecting the \fInpts\fR points specified by the \fIxpts\fR and +\fIypts\fR array in the desired \fIcolor\fR. +.sp 0.5 +.us "Synopsis" +.nf + \f(CWint cdl_markPolyline (CDLPtr cdl, int *xpts, int *ypts, + int npts, int color)\fR +.fi +.NH 3 +Polygon +.LP + The \fBcdl_markPolygon()\fR procedure is used to draw a closed +polygon consisting of \fInpts\fR vertices specified by the \fIxpts\fR and +\fIypts\fR array in the desired \fIcolor\fR. The last point in the array +will automatically be connected to the first point by the procedure. +If the \fIfill\fR flag is set the circle will be filled with the marker color. +.sp 0.5 +.us "Synopsis" +.nf + \f(CWint cdl_markPolygon (CDLPtr cdl, int *xpts, int *ypts, + int npts, int fill, int color)\fR +.fi +.NH 3 +Ellipse +.LP + The \fBcdl_markEllipse()\fR procedure is used to draw an ellipse of the +specified color with a center at (\fIx,y\fR) and semimajor-axis \fIxrad\fR +and semiminor-axis \fIyrad\fR pixels long. A rotation angle for the ellipse +may be specified by passing a non-zero \fIangle\fR argument, the angle is +measured in degrees from the positive x-axis. +If the \fIfill\fR flag is set the circle will be filled with the marker color. +.sp 0.5 +.us "Synopsis" +.nf + \f(CWint cdl_markEllipse (CDLPtr cdl, int x, int y, int xrad, + int yrad, float ang, int fill, int color)\fR +.fi +.NH 3 +Circular Annuli +.LP + The \fBcdl_markCircAnnuli()\fR procedure is used to draw +\fInannuli\fR circles separated by \fIsep\fR pixels each. The circle is +centered at (\fIx,y\fR) with an initial radius of \fIradius\fR pixels. +.sp 0.5 +.us "Synopsis" +.nf + \f(CWint cdl_markCircAnnuli (CDLPtr cdl, int x, int y, int radius, + int nannuli, int sep, int color)\fR +.fi +.NH 3 +Elliptical Annuli +.LP + The \fBcdl_markEllipAnnuli()\fR procedure is used to draw +\fInannuli\fR ellipses separated by \fIsep\fR pixels each. The ellipse is +centered at (\fIx,y\fR) with an initial semimajor and semiminor axis +specified by the \fIxrad\fR and \fIyrad\fR arguments. Each ellipse will +be optionally rotate by an \fIangle\fR degrees as measured from the positive +x-axis. +.sp 0.5 +.us "Synopsis" +.nf + \f(CWint cdl_markEllipAnnuli (CDLPtr cdl, x, y, xrad, yrad, ang, + int nannuli, int sep, int color)\fR +.fi +.NH 3 +Text +.LP + The \fBcdl_markText()\fR procedure is used to draw a text string +specified by \fIstr\fR argument with an initial position at (\fIx,y\fR) +and optionally rotated by \fIangle\fR degrees as measured from the positive +x-axis. The default \fIsize\fR is 1.0 and is approximately a 6x13 font, +the font size may be scaled by any fractional amount. +.sp 0.5 +.us "Synopsis" +.nf + \f(CWint cdl_markText (CDLPtr cdl, int x, int y, char *str, + float size, float angle, int color)\fR +.fi +.NH 2 +Text Fonts +.LP + The \fBcdl_setFont()\fR procedure is used to choose between one +of four available fonts as the text marker default: Roman, Greek, Futura, +and Times respectively. By default the Roman font will be used. +.sp 0.5 +.us "Synopsis" +.nf + \f(CWvoid cdl_setFont (CDLPtr cdl, int font)\fR +.fi +A complete listing of the Greek character mappings can be found in the file +'greek.ps' in the 'doc' subdirectory of the CDL distribution. +.NH 3 +In-Line Font Changes +.LP + Text markers are drawn using the font selected with the cdl_setFont() +routine, however fonts may be change within a string itself (e.g. to set +a Greek character) using a \\f escape sequence. The escape is followed +by the character 'R' to set a Roman font, 'G' for Greek, 'F' for futura +and 'T' for Times. Any number of escapes are permitted within a string, +the font change will remain in effect until it is changed, or the end of +string at which point any subsequent strings will again be drawn with the +default font. Additionally a 'P' in the escape sequence will change the +font to the one previously used, whatever that may be. +.LP + The CDL also supports a sub/superscripting of text which is also +done with the font escapes. In this case the escape character followed by a +'U' produces a superscript and a 'D' produces a subscript. The changes may +be nested permitting several levels of sub/superscripts, these escapes may +also be used in conjustion with a font change to cause the sub/superscript +to be drawn with a different font. A superscript escape will remain in +effect until the end of the string or a \\fD escape is seen. Similary a +subscript remains in effect until the end of the string of a \\fU escape. +.TS +center; +c s +l l. +Summary of Font Escapes +.sp 0.5 +\\\\fR change to Roman font +\\\\fG change to Greek font +\\\\fF change to Futura font +\\\\fT change to Times font +\\\\fP change to previous font +\\\\fU begin superscripted text +\\\\fD begin subscripted text +.TE +.NH 2 +Deleting Markers +.LP + When markers are drawn the underlying subraster is first saved to +an internal structure, erasure is done by simply redisplaying the saved +raster. Problems can arise however when markers overlap; when deleting a +marker that is \fIunder\fR another marker the original pixels can overwrite +the pixels of the marker on top. This is an unfortunate side effect of the +simple scheme used in this version of the package, users can call the +\fBcdl_redrawOverlay()\fR procedure to help clean up any artifacts left +behind. +.NH 3 +Individual Markers +.LP + The \fBcdl_deleteMark()\fR procedure is used to delete a single +marker from the display(). The (\fIx,y\fR) argument is either the center +position of the marker if that is know by the application, more typically +it will be an approximate position. In the latter case the marker whose +center is closest to this position will be deleted. For markers with no +defined center the distance used to decide if the marker should be +deleted is the distance from the argument position to the edge of the +marker. For example, distance from a box or polygon is measured as the +distance from to one of the sides, for text it is the distance to the +start of the text string. There is no way to \fIun\fRdelete a marker other +than to redraw it. +.sp 0.5 +.us "Synopsis" +.nf + \f(CWint cdl_deleteMark (CDLPtr cdl, int x, int y)\fR +.fi +.NH 3 +The Entire Overlay +.LP + To erase all markers currently displayed use the +\fBcdl_clearOverlay()\fR procedure. Markers are erased in the reverse order +they were drawn to help reduce the chance that overlaying markers will leave +stray pixels. +.sp 0.5 +.us "Synopsis" +.nf + \f(CWint cdl_clearOverlay (CDLPtr cdl)\fR +.fi +.NH 2 +Redraw +.LP + The \fBcdl_redrawOverlay()\fR procedure can be used to redraw all +markers currently in the display list. This is sometimes needed when +subraster I/O procedures are used to redisplay subregions and overwrite +existing markers. +.sp 0.5 +.us "Synopsis" +.nf + \f(CWint cdl_redrawOverlay (CDLPtr cdl)\fR +.fi +.NH +Fortran Language Binding Notes +.LP + The Fortran languange binding routines are implemented in C but +should be accessible from any fortran program as though they were real +fortran subroutines. The calling sequences are the same as with the C +library routines with the following exceptions: +.IP +\(bu The CDL package pointer is maintained internally so no 'cdl' pointer is +passed in the fortran interface. +.IP +\(bu All routines which are integer procedures in the C interface return an +extra 'ier' argument to contain the error flag. All Fortran functions are +implemented as subroutines. +.IP +\(bu The procedure names are the same except that \fIcdl_\fR has been +replaced with \fIcf\fR in the fortran binding. If your compiler is +case-sensitive then use all lower case letters. +.LP +The binding has been tested on a number of different platforms without +problems. The procedure names haven't been restricted to the traditional +6-character fortran names since most modern compilers can handle longer +names, if yours isn't one of them contact \fIiraf@noao.edu\fR for help +in changing the names. +.LP + Since the CDL is implemented as a set of C routines, the one aspect +that cannot be overlooked in the fortran binding is the between Fortran and +C storage order for arrays. In most cases this will not be a problem since +the CDL routines are just passing around pointers even if they live for a +short while in a fortran program. The problem comes when using the fortran +program to read the arrays, for example in using the array returned by the +\fBcfreadIRAF()\fR procedure, or when passing in arrays for display that +originated in the user's fortran code. In these cases the array \fBmust\fR +be transposed to be interpreted correctly. It was assumed that in most +applications arrays returned by CDL procedures would be immediately passed +to other CDL procedures so having the binding routines +transpose the array to/from +Fortran storage order was unnecessarily inefficient. This may be changed in +later releases if required. + +.NH +SPP Language Binding Notes +.LP + The SPP language binding is experimental and is intended to provide +a way to quickly prototype tasks, it should not be used in production code +as it may not be as portable as the rest of the task. In essence this +binding is layer on top of the Fortran binding since most IRAF platforms +still use Fortran as the intermediate code. The calling sequences are the +same as with the Fortran library routines with the following caveats: +.IP +\(bu The 'cdlspp.h' SPP include file is required by all files which call +CDL routines. The binding names are actually SPP macros to resolve the +current 6 character limit on procedure name. +.IP +\(bu The CDL package pointer is maintained internally so no 'cdl' pointer is +passed in the fortran interface. +.IP +\(bu All routines which are integer procedures in the C interface return an +extra 'ier' argument to contain the error flag. All SPP functions are +implemented as subroutines. +.IP +\(bu The procedure names are the same except that they are all upper case +and the \fIcdl_\fR has been replaced with \fICDS_\fR in the SPP binding. The +upper case is required. + +.NH +IIS Protocol Description +.LP + The communications protocol used by the CDL and servers such as +\fIXImtool\fR and \fISAOimage\fR, is a slightly modified version of that used +by the IIS Model 70. All operations are initiated by sending a header +packet containing a \fIthing id\fR (tid) and \fIsubunit\fR selecting the +function to be performed, optionally followed by data up to 32K bytes long. +The IIS header packet used is defined as +.nf + \f(CWstruct iism70 { + short tid; + short thingct; + short subunit; + short checksum; + short x, y, z; + short t; + };\fR +.fi + +The \fIthing count\fR field contains the negative number of bytes of data +that will be sent following the header packet. The IIS header checksum is +computed as +.nf +\f(CW + checksum = 0177777 - (tid + subunit + thingct + x + y + z + t); +\fR +.fi +The four IIS registers are set differently depending on the operation, a +summary of the header packets for each operation is summarized below. + +.ce 1 +\fBIIS Header Packet Summary\fR +.TS +tab(:); +c c c c c c c c c. +:TID:Subunit:Thingct:X:Y:Z:T:Data +.T& +l | l | l | c | c | c | l | l | l |. +:_:_:_:_:_:_:_:_ +Read Data:IIS_READ\fB|\fPPACKED:MEMORY:-nbytes:x:y:frame:-:nbytes +Write Data:IIS_WRITE\fB|\fPPACKED:MEMORY:-nbytes:x:y:frame:-:nbytes +Read Cursor:IIS_READ:IMCURSOR:-:-:-:-:-:- +Write Cursor:IIS_WRITE:IMCURSOR:-:x:y:wcs:-:- +Set Frame:IIS_WRITE:LUT\fB|\fPCOMMAND:-1:-:-:-:-:2 +Write WCS:IIS_WRITE\fB|\fPPACKED:WCS:-N:-:-:frame:fb:N +Read WCS:IIS_READ:WCS:-:-:-:-:-:320 +Erase Frame:IIS_WRITE \fB|\fP fb:FEEDBACK:-:-:-:frame:-:- +:_:_:_:_:_:_:_:_ +.TE +.TS +l l l. +Where nbytes = number of bytes expected or written + x = x postion of operation in frame buffer coords + y = y postion of operation in frame buffer coords + frame = frame number (passed as bitflag (i.e. 1, 2 ,4 8, etc) + fb = frame buffer config number (zero indexed) + N = length of WCS string + wcs = WCS number (usually zero) + Data = the number of bytes of data to be read or written following the header packet. + + IIS_WRITE = 0400000 + IIS_READ = 0100000 + COMMAND = 0100000 + PACKED = 0040000 + IMC_SAMPLE = 0040000 + + MEMORY = 001 + LUT = 002 + FEEDBACK = 005 + IMCURSOR = 020 + WCS = 021 +.TE +.LP +TID fields can be logically OR'd with the PACKED flag indicating the number +of data bytes is exactly \fIthingct\fR bytes long, otherwise \fIthingct\fR +must be specified as half the number of data bytes. In a cursor read, if +the IIS_READ flag is OR'd with IMC_SAMPLE the logical cursor position (i.e. +the last value read or set) is returned immediately, otherwise the server +will wait for a keystroke to be hit before returning a string containing the +(x,y) position, wcs of the read, and the keystroke. When setting the frame +you must send a short integer in the data containing the frame selected. +.bp +.NH +C Interface Summary +.LP +.in 0.5i +#include "\fBcdl.h\fR" +.in -0.5i + +.TS +center; +r l. +CDLPtr \fBcdl_open\fR (imtdev) +int \fBcdl_displayPix\fR (cdl, pix, nx, ny, bitpix, frame, fbconfig, zscale) +char \fBcdl_readCursor\fR (cdl, sample, x, y, key) +int \fBcdl_setCursor\fR (cdl, x, y, wcs) +int \fBcdl_setWCS\fR (cdl, name, title, a, b, c, d, tx, ty, z1, z2, zt) +int \fBcdl_getWCS\fR (cdl, name, title, a, b, c, d, tx, ty, z1, z2, zt) +void \fBcdl_setFrame\fR (cdl, frame) +int \fBcdl_clearFrame\fR (cdl) +void \fBcdl_close\fR (cdl) + +int \fBcdl_displayIRAF\fR (cdl, fname, band, frame, fbconfig, zscale) +int \fBcdl_isIRAF\fR (fname) +int \fBcdl_readIRAF\fR (fname, band, pix, nx, ny, bitpix) + +int \fBcdl_displayFITS\fR (cdl, fname, frame, fbconfig, zscale) +int \fBcdl_isFITS\fR (fname) +int \fBcdl_readFITS\fR (fname, pix, nx, ny, bitpix) + +void \fBcdl_computeZscale\fR (cdl, pix, nx, ny, bitpix, z1, z2) +void \fBcdl_zscaleImage\fR (cdl, pix, nx, ny, bitpix, z1, z2) + +int \fBcdl_printPix\fR (cdl, cmd, pix, nx, ny, annotate) +int \fBcdl_printPixToFile\fR (cdl, fname, pix, nx, ny, annotate) + +int \fBcdl_readImage\fR (cdl, pix, nx, ny) +int \fBcdl_readFrameBuffer\fR (cdl, pix, nx, ny) +int \fBcdl_readSubRaster\fR (cdl, lx, ly, nx, ny, pix) +int \fBcdl_writeSubRaster\fR (cdl, lx, ly, nx, ny, pix) + +void \fBcdl_selectFB\fR (cdl, nx, ny, fb, w, h, nf, reset) +void \fBcdl_setFBConfig\fR (cdl, configno) +void \fBcdl_getFBConfig\fR (cdl, configno, w, h, nf) +void \fBcdl_lookupFBSize\fR (cdl, configno, w, h, nf) + +void \fBcdl_setZTrans\fR (cdl, ztrans) +void \fBcdl_setZScale\fR (cdl, z1, z2) +void \fBcdl_setSample\fR (cdl, nsample) +void \fBcdl_setSampleLines\fR (cdl, nlines) +void \fBcdl_setContrast\fR (cdl, contrast) +void \fBcdl_setName\fR (cdl, imname) +void \fBcdl_setTitle\fR (cdl, imtitle) + +void \fBcdl_getFrame\fR (cdl, frame) +void \fBcdl_getZTrans\fR (cdl, ztrans) +void \fBcdl_getZScale\fR (cdl, z1, z2) +void \fBcdl_getSample\fR (cdl, nsample) +void \fBcdl_getSampleLines\fR (cdl, nlines) +void \fBcdl_getContrast\fR (cdl, contrast) +void \fBcdl_getName\fR (cdl, imname) +void \fBcdl_getTitle\fR (cdl, imtitle) + +int \fBcdl_mapFrame\fR (cdl, frame) +int \fBcdl_markPoint\fR (cdl, x, y, number, size, type, color) +int \fBcdl_markPointLabel\fR (cdl, x, y, label, size, type, color) +int \fBcdl_markLine\fR (cdl, xs, ys, xe, ye, color) +int \fBcdl_markBox\fR (cdl, lx, ly, ux, uy, fill, color) +int \fBcdl_markPolygon\fR (cdl, xarray, yarray, npts, fill, color) +int \fBcdl_markPolyline\fR (cdl, xarray, yarray, npts, color) +int \fBcdl_markCircle\fR (cdl, x, y, radius, fill, color) +int \fBcdl_markCircAnnuli\fR (cdl, x, y, radius, nannuli, sep, color) +int \fBcdl_markEllipse\fR (cdl, x, y, xrad, yrad, rotang, fill, color) +int \fBcdl_markEllipAnnuli\fR (cdl, x, y, xrad, yrad, ang, nannuli, sep, color) +int \fBcdl_markText\fR (cdl, x, y, str, size, angle, color) +int \fBcdl_deleteMark\fR (cdl, x, y) +int \fBcdl_clearOverlay\fR (cdl) +int \fBcdl_redrawOverlay\fR (cdl) +.TE + +.bp +.NH +C Example Tasks +.LP + The examples shown here are for demonstration purposes only. They +are based on working example tasks in the CDL source \fIexamples\fR +subdirectory, see the programs there for the full program listing. + +.NH 2 +Display Example +.LP +.ps -2 +.vs -2 +.nf +\f(CW +#include <stdio.h> +#include <unistd.h> +#include "cdl.h" + +/* \fIDISPLAY -- Example task to display an image as a command-line task. + * This task is meant to show three ways the CDL can be used to display + * an image, see the code comments for a description of each method. + * + * Examples: + * To display a simple IRAF or FITS file: + * % ./display -frame 2 image.imh + * % ./display image.fits + * + * To display a FITS file as a raw image: + * % ./display -nx 512 -ny 512 -depth 16 -hskip 5760 -raw dpix.fits + * + * Usage: + * display [-depth N] [-fits] [-frame N] [-fbconfig N] [-hskip N] + * [-iraf] [-nozscale] [-nx N] [-ny N] [-raw] [-zscale] file\fP + */ + +#define NONE -1 +#define IRAF 0 +#define FITS 1 +#define RAW 2 + +main (argc, argv) +int argc; +char *argv[]; +{ + CDLPtr cdl; + char *fname; + int i, status = 0, frame = 1, fbconfig = 0, zscale = 1; + int format = NONE, nx = 0, ny = 0, depth = 8, hskip = 0; + float z1, z2; + int fb_w, fb_h, nf; + unsigned char *pix = NULL; + + /* \fIProcess the command line options.\fP */ + if (argc > 1) { + for (i=1; i < argc; i++) { + if (strcmp (argv[i], "-depth") == 0) depth = atoi (argv[++i]); + else if (strcmp (argv[i], "-fits") == 0) format = FITS; + else if (strcmp (argv[i], "-frame") == 0) frame = atoi (argv[++i]); + else if (strcmp (argv[i], "-fbconfig") == 0) fbconfig = atoi (argv[++i]); + else if (strcmp (argv[i], "-hskip") == 0) hskip = atoi (argv[++i]); + else if (strcmp (argv[i], "-iraf") == 0) format = IRAF; + else if (strcmp (argv[i], "-nozscale") == 0) zscale = 0; + else if (strcmp (argv[i], "-nx") == 0) nx = atoi (argv[++i]); + else if (strcmp (argv[i], "-ny") == 0) ny = atoi (argv[++i]); + else if (strcmp (argv[i], "-raw") == 0) format = RAW; + else if (strcmp (argv[i], "-zscale") == 0) zscale = 1; + } + } + + /* \fIOpen the package and a connection to the server.\fP */ + if (!(cdl = \fBcdl_open\fP ((char *)getenv("IMTDEV"))) ) + exit (-1); + + fname = argv[argc-1]; + + /* \fIMETHOD 1: Displays the image using the high-level format display + * call. Display as an IRAF image if the option was set indicating + * this is the format, otherwise test the file to see if it is anyway.\fP + */ + if (format == IRAF || (format == NONE && \fBcdl_isIRAF\fP (fname))) { + status = \fBcdl_displayIRAF\fP (cdl, fname, 1, frame, FB_AUTO, zscale); + + /* \fIMETHOD 2: Uses the CDL procedure for getting image pixels from + * a known format, minimal work required to display an image. The + * point here is that you can use this method to process the image + * yourself prior to display, e.g. subsample the pixels, apply a user + * LUT, etc but still use the CDL to get the raw image and do the + * display.\fP + */ + } else if (format == FITS || (format == NONE && \fBcdl_isFITS\fP (fname))) { + + /* \fIGet the FITS image pixels, exit w/ an error status if something + * went wrong, the procedure will print what that was.\fP + */ + if (\fBcdl_readFITS\fP (fname, &pix, &nx, &ny, &depth)) { + \fBcdl_close\fP (cdl); /* close the package */ + exit (1); /* exit w/ error code */ + } + + /* \fINow select a frame buffer large enough for the image. The + * fbconfig number is passed in the WCS packet, but the display + * call below will compute the correct WCS for the image and + * transmit that prior to display, all we're doing here is + * setting up the FB to be used.\fP + */ + if (fbconfig == 0) + cdl_selectFB (cdl, nx, ny, &fbconfig, &fb_w, &fb_h, &nf, 0); + + /* \fILastly, display the pixels to the requested frame, do any + * zscaling requested using the CDL procedure.\fP + */ + status = \fBcdl_displayPix\fP (cdl, pix, nx, ny, depth, frame, + fbconfig, zscale); + + /* \fIMETHOD 3: Displays an image of raw pixels. The client code is + * responsible for reading the image and calling all the procedures + * needed for image display, initialize the frame, zscaling pix, etc. + * While we assume a simple raster format in this program, the user + * code can read a compressed image format such as GIF, mosaic multiple + * images for display as a single image, or just about anything that + * produces a raster for display. The intent here is to show all the + * lowest level calls needed for displaying the image.\fP + */ + } else if (format == RAW) { + FILE *fd; + int lx, ly; + + if (nx == 0 || ny == 0) { + fprintf (stderr, "No size given for raw data.\\n"); + exit (1); + } + + /* \fIOpen the image file if we can.\fP */ + if (fd = fopen (fname, "r")) { + + /* \fISeek to the offset specified.\fP */ + lseek (fileno(fd), (off_t) hskip, SEEK_SET); + + /* \fIAllocate the pixel pointer and read the data.\fP */ + pix = (unsigned char *) malloc (nx * ny * (depth / 8)); + fread (pix, depth/8, nx * ny, fd); + + /* \fIIf we're zscaling and depth is more than 8-bits, do that.\fP */ + if (zscale && depth > 8) { + \fBcdl_computeZscale\fP (cdl, pix, nx, ny, depth, &z1, &z2); + \fBcdl_zscaleImage\fP (cdl, &pix, nx, ny, depth, z1, z2); + } + + /* \fINow select a frame buffer large enough for the image. We'll + * ask that this be reset but the change won't go to the server + * until we send in a WCS, so compute that as well. For the + * WCS we assume a simple linear transform where the image is + * Y-flipped, the (x,y) translation is computed so it is correct + * for an frame buffer >= than the image size.\fP + */ + \fBcdl_selectFB\fP(cdl, nx, ny, &fbconfig, &fb_w, &fb_h, &nf,1); + \fBcdl_setWCS\fP (cdl, fname, NULL, 1., 0., 0., -1., + (float) (nx / 2) - (fb_w / 2) + 1, /* \fIX trans.\fP */ + (float) (fb_h / 2) + (ny / 2), /* \fIY trans.\fP */ + z1, z2, CDL_LINEAR); /* \fIZ transform\fP */ + + /* \fISelect and clear the requested frame prior to display.\fP */ + \fBcdl_setFrame\fP (cdl, frame); + \fBcdl_clearFrame\fP (cdl); + + /* \fINow display the pixels. We'll compute the image placement + * ourselves and write the image as a raw subraster of the frame + * buffer. In this case we'll center the image, but the CDL + * cdl_writeSubRaster() procedure can be used to write arbitrary + * rasters at any point in the frame buffer.\fP + */ + lx = (fb_w / 2) - (nx / 2); + ly = fb_h - ((fb_h / 2) + (ny / 2)); + status = \fBcdl_writeSubRaster\fP (cdl, lx, ly, nx, ny, pix); + } else + status = 1; + } else { + if (access (fname, F_OK) == 0) + fprintf (stderr, "'%s': unknown image format.\\n", fname); + else + fprintf (stderr, "'%s': image does not exist.\\n", fname); + status = 1; + } + + /* \fINow just free the pixel pointer to clean up.\fP */ + if (pix) + free ((unsigned char *) pix); + \fBcdl_close\fP (cdl); /* \fIclose the package\fP */ + exit (status); +} +\fR +.fi +.vs +2 +.ps +2 +.bp +.NH 2 +Interactive Graphics Overlay Example +.LP +.ps -2 +.vs -2 +.nf +\f(CW +#include <stdio.h> +#include <unistd.h> +#include <math.h> +#include "cdl.h" + +/* \fI + * TVMARK -- Example task for displaying an marking images. This program + * can be used to either display an image and overlay points defined in + * a coordinate file, map an existing display frame for marking, or option- + * ally enter a cursor command loop after either of these providing other + * marking capability. All options support minimum match. + * + * Examples: + * % tvmark dpix.fits + * % tvmark -coords coords -color 205 dpix.fits + * % tvmark -frame 2 + * % tvmark -coords coords -interactive dpix.fits + * + * Usage: + * tvmark [-frame N] [-fbconfig N] [-coords <file>] [-size N] [-color N] + * [-nolabel] [-fill] [-interactive] [image]\fP + */ + +main (argc, argv) +int argc; +char *argv[]; +{ + CDLPtr cdl; + char *fname = NULL, *cfname = NULL; + int i, status = 0, fill = 0, frame = 1, fb = FB_AUTO, zscale = 1; + int color = 201, label = 1, size = 9, interactive = 0; + float z1, z2; + int fb_w, fb_h, nf; + unsigned char *pix = NULL; + + /* \fIProcess the command line options.\fP */ + if (argc > 1) { + for (i=1; i < argc; i++) { + if (strncmp(argv[i], "-color",4) == 0) color = atoi (argv[++i]); + else if (strncmp(argv[i], "-coords",4) == 0) cfname = argv[++i]; + else if (strncmp(argv[i], "-fbconfig",3) == 0) fb = atoi (argv[++i]); + else if (strncmp(argv[i], "-fill",4) == 0) fill = 1; + else if (strncmp(argv[i], "-frame",3) == 0) frame = atoi (argv[++i]); + else if (strncmp(argv[i], "-interactive",4) == 0) interactive = 1; + else if (strncmp(argv[i], "-nolabel",4) == 0) label = 0; + else if (strncmp(argv[i], "-nozscale",4) == 0) zscale = 0; + else if (strncmp(argv[i], "-size",2) == 0) size = atoi (argv[++i]); + else + fname = argv[i]; + } + } + + /* \fIOpen the package and a connection to the server.\fP */ + if (!(cdl = \fBcdl_open\fP ((char *)getenv("IMTDEV"))) ) + exit (-1); + + /* \fIIf an image was specified display it first, otherwise assume the + * image has already been loaded in the frame and mark that.\fP + */ + if (fname) { + if (\fBcdl_isIRAF\fP (fname)) + status = \fBcdl_displayIRAF\fP (cdl, fname, 1, frame, fb, zscale); + else if (\fBcdl_isFITS\fP (fname)) + status = \fBcdl_displayFITS\fP (cdl, fname, frame, fb, zscale); + else { + if (access (cfname, F_OK) == 0) + fprintf (stderr, "'%s': unknown image format.\\n", fname); + else + fprintf (stderr, "'%s': image doesn't exist.\\n", fname); + status = 1; + } + if (status) goto err_; + } else { + + /* \fIIf we've requested a special frame buffer, set it now.\fP */ + if (fb > 0) + \fBcdl_setFBConfig\fP (cdl, fb); + + /* \fIMap the current display frame for use as an image.\fP */ + \fBcdl_mapFrame\fP (cdl, frame); + } + + /* \fIIf a coordinate file was specified read the file and mark those + * coords with points.\fP + */ + if (cfname) { + if (access (cfname, F_OK) == 0) { + FILE *fp; + int i, x, y; + + if (fp = fopen (cfname, "r")) { + /* \fIThe coord file is assumed to be simply a file containing + * (x,y) pairs, one per line. Scan the file and mark each + * point. We do no bounds checking to see if the coords + * are correct for the frame, marker type is fixed.\fP + */ + i = 1; + while (fscanf (fp, "%d %d", &x, &y) != EOF) { + if (label) + \fBcdl_markPoint\fP (cdl, x, y, i++, size, M_STAR, color); + else + \fBcdl_markPoint\fP (cdl, x, y, 0, size, M_STAR, color); + } + + } else + fprintf (stderr, "cannot open coord file '%s'.\\n", cfname); + } else + fprintf (stderr, "'%s': coord file doesn't exist, ignoring.\\n", cfname); + } + + /* \fILastly, start up an interactive cursor loop if needed.\fP */ + if (interactive) + tvmInteractive (cdl, label, fill, color, size); + + /* \fIClose the package and clean up.\fP */ +err_: \fBcdl_close\fP (cdl); + exit (status); +} + +/* \fITVMINTERACTIVE -- Process commands interactively.\fP */ + +tvmInteractive (cdl, label, fill, color, size) +CDLPtr cdl; +int label, fill, color, size; +{ + float angle = 0.0, rx, ry, txsize = 1.; + int nx, ny, i, x, y, x2, y2; + int number=1, radius=11, xrad=11, yrad=6, nannuli=3, sep=5; + char key, cmd[SZ_NAME], str[SZ_NAME]; + unsigned char *pix; + + /* \fIProcess commands until a 'q' keystrke is hit.\fP */ + while (\fBcdl_readCursor\fP (cdl, 0, &rx, &ry, &key) != 'q') { + x = (int) (rx + 0.5); /* \fIconvert to int pixels\fP */ + y = (int) (ry + 0.5); + + switch (key) { + case ':': /* \fIprocess a colon command\fP */ + putchar (':'); + gets (str); + for (i=0; str[i] != ' ' && str[i]; i++) + cmd[i] = str[i]; + cmd[i++] = '\0'; + + if (strcmp (cmd, "angle") == 0) angle = atof (&str[i]); + else if (strcmp (cmd, "color") == 0) color = atoi (&str[i]); + else if (strcmp (cmd, "fill") == 0) fill = atoi (&str[i]); + else if (strcmp (cmd, "number") == 0) number = atoi (&str[i]); + else if (strcmp (cmd, "nannuli") == 0) nannuli = atoi (&str[i]); + else if (strcmp (cmd, "label") == 0) label = atoi (&str[i]); + else if (strcmp (cmd, "sep") == 0) sep = atoi (&str[i]); + else if (strcmp (cmd, "size") == 0) size = atoi (&str[i]); + else if (strcmp (cmd, "txsize") == 0) txsize = atof (&str[i]); + else if (strcmp (cmd, "xrad") == 0) xrad = atoi (&str[i]); + else if (strcmp (cmd, "yrad") == 0) yrad = atoi (&str[i]); + else if (strcmp (cmd, "print") == 0) { + \fBcdl_readFrameBuffer\fP (cdl, &pix, &nx, &ny); + \fBcdl_printPix\fP (cdl, NULL, pix, nx, ny, 1); + } else if (strcmp (cmd, "snap") == 0) { + \fBcdl_readFrameBuffer\fP (cdl, &pix, &nx, &ny); + \fBcdl_printPixToFile\fP (cdl, &str[i], pix, nx, ny, 1); + } else if (strcmp (cmd, "status") == 0) { + printf ("angle = %-5.3g\tcolor = %d\t", angle, color); + printf ("fill = %-5d\tnumber = %d\\n", fill, number); + printf ("nannuli = %-5d\tsep = %d\t", nannuli, sep); + printf ("size = %-5d\ttxsize = %g\\n", size, txsize); + printf ("xrad = %-5d\tyrad = %d\t", xrad, yrad); + printf ("label = %-5d\\n", label); + } + break; + + case '?': + /* ......\fIhelp procedures\fP */ + break; + + case 'p': /* \fIplus mark\fP */ + \fBcdl_markPoint\fP (cdl, x, y, (label ? number++ : 0), size, M_PLUS, color); + break; + case 'x': /* \fIcross mark\fP */ + \fBcdl_markPoint\fP (cdl, x, y, (label ? number++ : 0), size, M_CROSS, color); + break; + case '.': /* \fIpoint mark\fP */ + \fBcdl_markPoint\fP (cdl, x, y, (label ? number++ : 0), size, M_POINT, color); + break; + case '*': /* \fIstar mark\fP */ + \fBcdl_markPoint\fP (cdl, x, y, (label ? number++ : 0), size, M_STAR, color); + break; + case '_': /* \fIhoriz dash mark\fP*/ + \fBcdl_markPoint\fP (cdl, x, y, (label ? number++ : 0), size, M_HBLINE, color); + break; + case '|': /* \fIvert dash mark\fP */ + \fBcdl_markPoint\fP (cdl, x, y, (label ? number++ : 0), size, M_VBLINE, color); + break; + case 'o': /* \fIcircle mark\fP */ + \fBcdl_markPoint\fP (cdl, x, y, (label ? number++ : 0), size, M_CIRCLE|fill, color); + break; + case 's': /* \fIsquare mark\fP */ + \fBcdl_markPoint\fP (cdl, x, y, (label ? number++ : 0), size, M_BOX|fill, color); + break; + case 'v': /* \fIdiamond mark\fP */ + \fBcdl_markPoint\fP (cdl, x, y, (label ? number++ : 0), size, M_DIAMOND|fill, color); + break; + + case 'b': /* \fIBox\fP */ + printf ("Hit another key to define the box...\\n"); + (void) \fBcdl_readCursor\fP (cdl, 0, &rx, &ry, &key); + x2 = (int) (rx + 0.5); y2 = (int) (ry + 0.5); + \fBcdl_markBox\fP (cdl, x, y, x2, y2, fill, color); + break; + case 'c': /* \fICircle\fP */ + printf ("Hit another key to set radius ...\\n"); + (void) \fBcdl_readCursor\fP (cdl, 0, &rx, &ry, &key); + x2 = (int) (rx + 0.5); y2 = (int) (ry + 0.5); + radius = (int) sqrt ((double) ((x2-x)*(x2-x) + (y2-y)*(y2-y))); + \fBcdl_markCircle\fP (cdl, x, y, radius, fill, color); + break; + case 'd': /* \fIDelete marker\fP */ + \fBcdl_deleteMark\fP (cdl, x, y); + break; + case 'e': /* \fIEllipse\fP */ + \fBcdl_markEllipse\fP (cdl, x, y, xrad, yrad, angle, fill, color); + break; + case 'l': /* \fILine\fP */ + printf ("Hit another key to set line endpoint...\\n"); + (void) \fBcdl_readCursor\fP (cdl, 0, &rx, &ry, &key); + x2 = (int) (rx + 0.5); y2 = (int) (ry + 0.5); + \fBcdl_markLine\fP (cdl, x, y, x2, y2, color); + break; + case 't': /* \fIText string\fP */ + printf ("Text string: "); + gets (str); + \fBcdl_markText\fP (cdl, x, y, str, txsize, angle, color); + break; + case 'C': /* \fICircular annuli\fP*/ + \fBcdl_markCircAnnuli\fP (cdl, x, y, radius, nannuli, sep, color); + break; + case 'D': /* \fIDelete all markers\fP*/ + \fBcdl_clearOverlay\fP (cdl); + break; + case 'E': /* \fIElliptical annuli\fP*/ + \fBcdl_markEllipAnnuli\fP (cdl, x, y, xrad, yrad, angle, nannuli, sep, color); + break; + default: + break; + } + } +} +\fR +.fi +.vs +2 +.ps +2 +.bp +.NH 2 +Image Mosaic Example +.LP +.in 0.5i +.ps -2 +.vs -2 +.nf +#include <stdio.h> +#include <unistd.h> +#\fBinclude "cdl.h"\fP + +/* \fIMOSAIC -- Example task to mosaic several images on a display. Demonstrates + * usage of low-level routines for complex display operations.\fP + */ + +main (argc, argv) +int argc; +char *argv[]; +{ + CDLPtr cdl; + char *fname = NULL; + int i, j, k, status=0, label=0, frame=1, fb=FB_AUTO, zscale=1; + int sample=1, pad=0, col=204, imx, imy, bitpix, nimages, nim; + int ii, xinit, rowx, rowy, nnx, nny, fb_w, fb_h, nf, mx, my, nx, ny; + float z1, z2; + unsigned char *pix = NULL; + + /* \fIProcess the command line options.\fP */ + if (argc > 1) { + for (i=1; i < argc; i++) { + if (strncmp (argv[i], "-fbconfig",3) == 0) fb=atoi(argv[++i]); + else if (strncmp (argv[i],"-frame",3) == 0) frame=atoi(argv[++i]); + else if (strncmp (argv[i],"-color",3) == 0) col=atoi(argv[++i]); + else if (strncmp (argv[i],"-label",4) == 0) label=1; + else if (strncmp (argv[i],"-nozscale",4) == 0) zscale=0; + else if (strncmp (argv[i],"-nx",3) == 0) nx=atoi(argv[++i]); + else if (strncmp (argv[i],"-ny",3) == 0) ny=atoi(argv[++i]); + else if (strncmp (argv[i],"-pad",4) == 0) pad=atoi(argv[++i]); + else if (strncmp (argv[i],"-sample",4) == 0) sample=atoi(argv[++i]); + else + break; + } + } + nimages = argc - i; + + /* \fIOpen the package and a connection to the server.\fP */ + if (!(cdl = \fBcdl_open\fP ((char *)getenv("IMTDEV"))) ) + exit (-1); + + /* \fIClear the frame to begin.\fP */ + (void) \fBcdl_clearFrame\fP (cdl); + + /* \fILoop over each of the images in the list.\fP */ + nim = rowx = rowy = nnx = nny = 0; + for (k=0; k < ny && nim < nimages; k++) { + rowy += nny + pad; + for (rowx = xinit, j=0; j < nx && nim < nimages; j++) { + + /* \fIGet the image name for display.\fP */ + fname = argv[i++]; + + /* \fIFigure out what kind of image it is and get the pixels.\fP */ + if (cdl_isIRAF (fname)) + status = \fBcdl_readIRAF\fP (fname, 1, &pix, &imx, &imy, &bitpix); + else if (cdl_isFITS (fname)) + status = \fBcdl_readFITS\fP (fname, &pix, &imx, &imy, &bitpix); + else { + fprintf(stderr, "'%s': unknown or nonexistant image.\\n", fname); + status = 1; + } + if (status) goto err_; + + /* \fICompute subsampled image size.\fP */ + if (sample > 1) + nnx = imx / sample, nny = imy / sample; + else + nnx = imx, nny = imy; + + /* \fIUnless we asked for a specific FB size find one large enough + * to handle the mosaic. We don't check to be sure what's + * returned is really large enough.\fP + */ + if (nim == 0 && fb == FB_AUTO) + \fBcdl_selectFB\fP (cdl, nx*nnx+(pad*(nx-1)), ny*nny+(pad*(ny-1)), &fb, &fb_w, &fb_h, &nf, 1); + else { + \fBcdl_setFBConfig\fP (cdl, fb); + \fBcdl_lookupFBSize\fP (cdl, fb, &fb_w, &fb_h, &nf); + } + + /* \fIDefine a WCS for the frame.\fP */ + \fBcdl_setWCS\fP (cdl, "image mosaic", "", 1., 0., 0., -1., 0., (float) ny*imy+(pad*(ny+1)), 1., 255., 1); + + /* \fIThe first time through figure out the placement so the + * entire mosaic is centered in the frame.\fP + */ + if (nim == 0) { + mx = (nx * nnx) + pad * (nx-1); + my = (ny * nny) + pad * (ny-1); + rowy = (fb_h - my) / 2; + xinit = rowx = (fb_w - mx) / 2; + } + + /* \fICompute the zscaled imaged pixels.\fP */ + if (zscale) { + \fBcdl_computeZscale\fP (cdl, pix, imx ,imy, bitpix, &z1, &z2); + \fBcdl_zscaleImage\fP (cdl, &pix, imx ,imy, bitpix, z1, z2); + } + + /* \fISubsample the image if requested.\fP */ + if (sample > 1) { + int l, m, n=0; + for (l=0; l < imy; l+=sample) + for (m=0; m < imx; m+=sample) + pix[n++] = pix[(l*imx)+m]; + } + + /* \fIWrite the image to the frame buffer.\fP */ + if (\fBcdl_writeSubRaster\fP (cdl, rowx, rowy, nnx, nny, pix)) goto err_; + + /* \fIDraw the image name as a label.\fP */ + if (label) \fBcdl_markText\fP (cdl, rowx+10, rowy+10, fname, 1., 0., col); + + nim++; rowx += nnx + pad; + } + } + + /* \fIClose the package and clean up.\fP */ +err_: \fBcdl_close\fP (cdl); + exit (status); +} +.fi +.vs +2 +.ps +2 +.in -0.5i + +.bp +.NH +Fortran Interface Summary +.LP +.in 0.5i +include "\fBcdlftn.inc\fR" +.in -0.5i + +.TS +center; +r l. +\fBcfopen\fR (imtdev, ier) +\fBcfdisplayPix\fR (pix, nx, ny, bitpix, frame, fbconfig, zscale, ier) +\fBcfreadCursor\fR (sample, x, y, key, ier) +\fBcfsetCursor\fR (x, y, wcs, ier) +\fBcfsetWCS\fR (name, title, a, b, c, d, tx, ty, z1, z2, zt, ier) +\fBcfgetWCS\fR (name, title, a, b, c, d, tx, ty, z1, z2, zt, ier) +\fBcfsetFrame\fR (frame) +\fBcfclearFrame\fR (ier) +\fBcfclose\fR () + +\fBcfdisplayIRAF\fR (fname, band, frame, fbconfig, zscale, ier) +\fBcfisIRAF\fR (fname, isiraf) +\fBcfreadIRAF\fR (fname, band, pix, nx, ny, bitpix, ier) + +\fBcfdisplayFITS\fR (fname, frame, fbconfig, zscale, ier) +\fBcfisFITS\fR (fname, isfits) +\fBcfreadFITS\fR (fname, pix, nx, ny, bitpix, ier) + +\fBcfcomputeZscale\fR (pix, nx, ny, bitpix, z1, z2) +\fBcfzscaleImage\fR (pix, nx, ny, bitpix, z1, z2) + +\fBcfprintPix\fR (cmd, pix, nx, ny, annotate, ier) +\fBcfprintPixToFile\fR (fname, pix, nx, ny, annotate, ier) + +\fBcfreadImage\fR (pix, nx, ny, ier) +\fBcfreadFrameBuffer\fR (pix, nx, ny, ier) +\fBcfreadSubRaster\fR (lx, ly, nx, ny, pix, ier) +\fBcfwriteSubRaster\fR (lx, ly, nx, ny, pix, ier) + +\fBcfselectFB\fR (nx, ny, fb, w, h, nf, reset) +\fBcfsetFBConfig\fR (configno) +\fBcfgetFBConfig\fR (configno, w, h, nf) +\fBcflookupFBSize\fR (configno, w, h, nf) + +\fBcfsetZTrans\fR (ztrans) +\fBcfsetZScale\fR (z1, z2) +\fBcfsetSample\fR (nsample) +\fBcfsetSampleLines\fR (nlines) +\fBcfsetContrast\fR (contrast) +\fBcfsetName\fR (imname) +\fBcfsetTitle\fR (imtitle) + +\fBcfgetFrame\fR (frame) +\fBcfgetZTrans\fR (ztrans) +\fBcfgetZScale\fR (z1, z2) +\fBcfgetSample\fR (nsample) +\fBcfgetSampleLines\fR (nlines) +\fBcfgetContrast\fR (contrast) +\fBcfgetName\fR (imname) +\fBcfgetTitle\fR (imtitle) + +\fBcfmapFrame\fR (frame, ier) +\fBcfmarkPoint\fR (x, y, number, size, type, color, ier) +\fBcfmarkPointLabel\fR (x, y, label, size, type, color, ier) +\fBcfmarkLine\fR (xs, ys, xe, ye, color, ier) +\fBcfmarkBox\fR (lx, ly, ux, uy, fill, color, ier) +\fBcfmarkPolygon\fR (xarray, yarray, npts, fill, color, ier) +\fBcfmarkPolyline\fR (xarray, yarray, npts, color, ier) +\fBcfmarkCircle\fR (x, y, radius, fill, color, ier) +\fBcfmarkCircAnnuli\fR (x, y, radius, nannuli, sep, color, ier) +\fBcfmarkEllipse\fR (x, y, xrad, yrad, rotang, fill, color, ier) +\fBcfmarkEllipAnnuli\fR (x, y, xrad, yrad, ang, nannuli, sep, color, ier) +\fBcfmarkText\fR (x, y, str, size, angle, color, ier) +\fBcfsetfont\fR (font) +\fBcfdeleteMark\fR (x, y, ier) +\fBcfclearOverlay\fR (ier) +\fBcfredrawOverlay\fR (ier) +.TE +.bp +.NH +Fortran Example Tasks +.LP + The examples shown here are for demonstration purposes only. They +are based on working example tasks in the CDL source \fIexamples\fR +subdirectory, see the programs there for the full program listing. + +.NH 2 +Display Example +.in 0.5i +.ps -2 +.vs -2 +.nf +\f(CW +C ======================================================================== +C FDISPLAY -- Example fortran program showing the use of the Client +C Display Library (CDL) Fortran interface for displaying images. +C ======================================================================== + + PROGRAM FDISPLAY + character*64 imname + +C \fIInitialize the CDL package\fP + call \fBcfopen\fP (0, ier) + if (ier .gt. 0) then + write (*,*) 'open: Error return from CDL' + goto 999 + endif + + write (*, "('Image Name: ', $)") + read (5, *) imname + write (*, "('Frame Number: ', $)") + read (5, *) iframe + write (*, "('Frame buffer configuration number: ', $)") + read (5, *) ifb + +C \fIIf we've got a FITS format image, go ahead and display it.\fP + call \fBcfisFITS\fP (imname, isfits) + if (isfits .gt. 0) then + call \fBcfdisplayFITS\fP (imname, iframe, ifb, 1, ier) + else +C \fIWe've got an IRAF format image, go ahead and display it.\fP + call \fBcfisIRAF\fP (imname, isiraf) + if (isiraf .gt. 0) then + call \fBcfdisplayIRAF\fP (imname, 1, iframe, ifb, 1, ier) + else +C \fIUnrecognized image, punt and exit.\fP + write (*,*) 'Unrecognized image format' + endif + endif + +C \fIClean up and exit.\fP +999 continue + call \fBcfclose\fP (ier) + end +\fR +.fi +.ps +2 +.vs +2 +.in -0.5i +.bp +.NH 2 +Interactive Graphics Overlay Example +.in 0.5i +.ps -2 +.vs -2 +.nf +\f(CW +C ========================================================================== +C FTVMARK -- Example fortran program showing the use of the Client +C Display Library (CDL) Fortran interface for doing graphics overlay. No +C checking of the error flag is done here for space considerations. +C ========================================================================== + + PROGRAM FTVMARK + include "\fBcdlftn.inc\fP" + character*64 imname + +C \fIInitialize the CDL package\fP + call \fBcfopen\fP (0, ier) + + write (*, "('Image Name: ', $)") + read (5, *) imname + write (*, "('Frame Number: ', $)") + read (5, *) iframe + write (*, "('Frame buffer configuration number: ', $)") + read (5, *) ifb + +C \fIIf we've got a FITS format image, go ahead and display it.\fP + call \fBcfisFITS\fP (imname, isfits) + if (isfits .gt. 0) then + call \fBcfdisplayFITS\fP (imname, iframe, ifb, 1, ier) + else +C \fIWe've got an IRAF format image, go ahead and display it.\fP + call \fBcfisIRAF\fP (imname, isiraf) + if (isiraf .gt. 0) then + call \fBcfdisplayIRAF\fP (imname, 1, iframe, ifb, 1, ier) + else +C \fINo valid image given, so map the current display for marking.\fP + call \fBcfmapFrame\fP (iframe) + endif + endif + +C \fINow that we've got an image displayed or mapped, enter a cursor loop to mark the image. \fP + call markInteractive () + +C \fIClean up and exit\fP +999 continue + call \fBcfclose\fP (ier) + end + +C \fIMARKINTERACTIVE -- Subroutine for processing the cursor loop.\fP + subroutine markInteractive () + include "\fBcdlftn.inc\fP" + real angle, rx, ry, txsize + integer nx, ny, x, y, x2, y2, fill, size, color + integer number, radius, xrad, yrad, nannuli, sep + character key + character*64 cmd, str + +C \fIAllocate a 1024x1024 array for pixels. \fP + character pix(1048576) + +C \fI....Initialize the local parameters to use\fP + +C \fIRead a cursor keystroke telling us what to do.\fP +10 call \fBcfreadCursor\fP (0, rx, ry, key, ier) + +C \fIRound the real cursor position to integer pixel positions.\fP + x = nint (rx + 0.5) + y = nint (ry + 0.5) + +C \fICheck the keystroke and take the appropriate action.\fP +C \fIColon Commands\fP + if (key .eq. ':') then +C \fIRead a three character command and value field and process the colon command\fP + read (*,'(A3, i4)') cmd, ival + if (cmd(1:3) .eq. 'ang') then + angle = real (ival) + else if (cmd(1:3) .eq. 'col') then + color = ival + else if (cmd(1:3) .eq. 'fil') then + fill = ival +\fI : + ....and so on to set local variables + :\fR + else if (cmd(1:3) .eq. 'pri') then +C \fIPrint contents of the current frame buffer\fP + call \fBcfreadFrameBuffer\fP (pix, nx, ny, ier) + call \fBcfprintPix\fP ("lpr", pix, nx, ny, 1, ier) + else if (cmd(1:3) .eq. 'sta') then + \fI....print out the status (value) of variables\fP + endif + +C \fIPoint Markers\fP + else if (key .eq. 'p') then + call \fBcfmarkPoint\fP (x, y, 1, size, M_PLUS, color, ier) + else if (key .eq. 'x') then + call \fBcfmarkPoint\fP (x, y, 1, size, M_CROSS, color, ier) + else if (key .eq. '_') then + call \fBcfmarkPoint\fP (x, y, 1, size, M_HBLINE, color, ier) + else if (key .eq. 'o') then +C \fIExample of a filled point marker \fP + call \fBcfmarkPoint\fP (x, y, 1, size, or(M_CIRCLE,fill), color, ier) +\fI : + ....and so on to set other types of point markers\fR + +C \fIOther Markers\fP + else if (key .eq. 'b') then + print '("Hit another key to define the box ....")' + call \fBcfreadCursor\fP (0, rx, ry, key, ier) + x2 = nint (rx + 0.5) + y2 = nint (ry + 0.5) + call \fBcfmarkBox\fP (x, y, x2, y2, fill, color, ier) + else if (key .eq. 'd') then + call \fBcfdeleteMark\fP (x, y, ier) + else if (key .eq. 'e') then + call \fBcfmarkEllipse\fP (x, y, xrad, yrad, angle, fill, color, ier) + else if (key .eq. 't') then + print '("Text string: ", $)' + read (*,'(A64)') str + call \fBcfmarkText\fP (x, y, str, txsize, angle, color, ier) +\fI : + ....and so on to set other types of markers\fR + +C \fIQuit\fP + else if (key .eq. 'q') then + goto 998 + endif + +C \fILoop back until we want to quit\fP + goto 10 +998 continue + end +\fR +.fi +.ps +2 +.vs +2 +.in -0.5i +.bp +.NH +SPP Interface Summary +.LP +.in 0.5i +#include "\fBcdlspp.h\fR" +.in -0.5i + +.TS +center; +r l. +\fBCDS_OPEN\fR (imtdev, ier) +\fBCDS_DISPLAYPIX\fR (pix, nx, ny, bitpix, frame, fbconfig, zscale, ier) +\fBCDS_READCURSOR\fR (sample, x, y, key, ier) +\fBCDS_SETCURSOR\fR (x, y, wcs, ier) +\fBCDS_SETWCS\fR (name, title, a, b, c, d, tx, ty, z1, z2, zt, ier) +\fBCDS_GETWCS\fR (name, title, a, b, c, d, tx, ty, z1, z2, zt, ier) +\fBCDS_SETFRAME\fR (frame) +\fBCDS_CLEARFRAME\fR (ier) +\fBCDS_CLOSE\fR () + +\fBCDS_DISPLAYIRAF\fR (fname, band, frame, fbconfig, zscale, ier) +\fBCDS_ISIRAF\fR (fname, isiraf) +\fBCDS_READIRAF\fR (fname, band, pix, nx, ny, bitpix, ier) + +\fBCDS_DISPLAYFITS\fR (fname, frame, fbconfig, zscale, ier) +\fBCDS_ISFITS\fR (fname, isfits) +\fBCDS_READFITS\fR (fname, pix, nx, ny, bitpix, ier) + +\fBCDS_COMPUTEZSCALE\fR (pix, nx, ny, bitpix, z1, z2) +\fBCDS_ZSCALEIMAGE\fR (pix, nx, ny, bitpix, z1, z2) + +\fBCDS_PRINTPIX\fR (cmd, pix, nx, ny, annotate, ier) +\fBCDS_PRINTPIXTOFILE\fR (fname, pix, nx, ny, annotate, ier) + +\fBCDS_READIMAGE\fR (pix, nx, ny, ier) +\fBCDS_READFRAMEBUFFER\fR (pix, nx, ny, ier) +\fBCDS_READSUBRASTER\fR (lx, ly, nx, ny, pix, ier) +\fBCDS_WRITESUBRASTER\fR (lx, ly, nx, ny, pix, ier) + +\fBCDS_SELECTFB\fR (nx, ny, fb, w, h, nf, reset) +\fBCDS_SETFBCONFIG\fR (configno) +\fBCDS_GETFBCONFIG\fR (configno, w, h, nf) +\fBCDS_LOOKUPFBSIZE\fR (configno, w, h, nf) + +\fBCDS_SETZTRANS\fR (ztrans) +\fBCDS_SETZSCALE\fR (z1, z2) +\fBCDS_SETSAMPLE\fR (nsample) +\fBCDS_SETSAMPLELINES\fR (nlines) +\fBCDS_SETCONTRAST\fR (contrast) +\fBCDS_SETNAME\fR (imname) +\fBCDS_SETTITLE\fR (imtitle) + +\fBCDS_GETFRAME\fR (frame) +\fBCDS_GETZTRANS\fR (ztrans) +\fBCDS_GETZSCALE\fR (z1, z2) +\fBCDS_GETSAMPLE\fR (nsample) +\fBCDS_GETSAMPLELINES\fR (nlines) +\fBCDS_GETCONTRAST\fR (contrast) +\fBCDS_GETNAME\fR (imname) +\fBCDS_GETTITLE\fR (imtitle) + +\fBCDS_MAPFRAME\fR (frame, ier) +\fBCDS_MARKPOINT\fR (x, y, number, size, type, color, ier) +\fBCDS_MARKPOINTLABEL\fR (x, y, label, size, type, color, ier) +\fBCDS_MARKLINE\fR (xs, ys, xe, ye, color, ier) +\fBCDS_MARKBOX\fR (lx, ly, ux, uy, fill, color, ier) +\fBCDS_MARKPOLYGON\fR (xarray, yarray, npts, fill, color, ier) +\fBCDS_MARKPOLYLINE\fR (xarray, yarray, npts, color, ier) +\fBCDS_MARKCIRCLE\fR (x, y, radius, fill, color, ier) +\fBCDS_MARKCIRCANNULI\fR (x, y, radius, nannuli, sep, color, ier) +\fBCDS_MARKELLIPSE\fR (x, y, xrad, yrad, rotang, fill, color, ier) +\fBCDS_MARKELLIPANNULI\fR (x, y, xrad, yrad, ang, nannuli, sep, color, ier) +\fBCDS_MARKTEXT\fR (x, y, str, size, angle, color, ier) +\fBCDS_SETFONT\fR (font) +\fBCDS_DELETEMARK\fR (x, y, ier) +\fBCDS_CLEAROVERLAY\fR (ier) +\fBCDS_REDRAWOVERLAY\fR (ier) +.TE |