aboutsummaryrefslogtreecommitdiff
path: root/vendor/x11iraf/cdl/examples/display.c
blob: 67b52c970c9e305ff87ba4d902f2015d3b1ffd05 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#include <stdio.h>
#ifdef ULTRIX
#include <sys/types.h>
#endif
#include <sys/types.h>
#include <unistd.h>
#include "cdl.h"

/* 
 *  DISPLAY -- 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
 *  and image, it is functional but perhaps not highly efficient for this
 *  reason.  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] 
 *	    [-ns N] [-nl N] [-log] file
 */

#define NONE	-1
#define	IRAF	 0
#define	FITS	 1
#define	RAW	 2

#define ABS(x)	(x > 0 ? x : -x)

#ifdef SOLARIS
char    *getcwd();
#else
char    *getwd();
#endif


main (argc, argv)
int	argc;
char	*argv[];
{
	CDLPtr	cdl;
	char 	*fname;
	int	i, log = 0, status = 0, frame = 1, fbconfig = 0, zscale = 1;
	int	format = NONE, nx = 0, ny = 0, depth = 8, hskip = 0;
	int	ns = -1, nl = -1;
	float 	z1, z2;
	int	fb_w, fb_h, nf;
	unsigned char *pix = NULL;
        char    *path_prefix = (char *) calloc (1025, sizeof(char));
        char    *path = (char *) calloc (512, sizeof(char));
        char    *node = (char *) calloc (512, sizeof(char));

	
	/* Process the command line options. */
	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], "-log") == 0)
		    log++;
                else if (strcmp (argv[i], "-nozscale") == 0)
		    zscale = 0;
                else if (strcmp (argv[i], "-ns") == 0)
		    ns = atoi (argv[++i]);
                else if (strcmp (argv[i], "-nl") == 0)
		    nl = atoi (argv[++i]);
                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;
	    }
	}

	/* Open the package and a connection to the server. */
	if (!(cdl = cdl_open ((char *)getenv("IMTDEV"))) )
	   exit (-1);

	fname = argv[argc-1];

	if (ns >  0)  cdl_setSample (cdl, ns);
	if (nl >  0)  cdl_setSampleLines (cdl, nl);
	if (log > 0)  cdl_setZTrans (cdl, CDL_LOG);

	/* METHOD 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.
	 */
	if (format == IRAF || (format == NONE && cdl_isIRAF (fname))) {
	    status = cdl_displayIRAF (cdl, fname, 1, frame,
		(fbconfig==0 ? FB_AUTO : fbconfig), zscale);


	/* METHOD 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 mthod 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.
	 */
	} else if (format == FITS || (format == NONE && cdl_isFITS (fname))) {
	    float *bscale, *bzero;
	    char  title[80];

	    /* Get the FITS image pixels, exit w/ an error status if something
	     * went wrong, the procedure will print what that was.
	     */
            if (cdl_readFITS (fname, &pix, &nx, &ny, &depth, title)) {
		cdl_close (cdl);		/* close the package  */
		exit (1);			/* exit w/ error code */
	    }

	    /* Now 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.
	     */
	    if (fbconfig == 0)
                cdl_selectFB (cdl, nx, ny, &fbconfig, &fb_w, &fb_h, &nf, 0);

	    /* Lastly, display the pixels to the requested frame, do any
	     * zscaling requested using the CDL procedure.  
	     */
	    (void) cdl_setTitle (cdl, title);
            (void) cdl_setName (cdl, fname);
            if (cdl_displayPix(cdl, pix, nx, ny, depth, frame, fbconfig,zscale))
                status = 1;
 
	    /* Now just free the pixel pointer to clean up.
	     */
	    free ((unsigned char *) pix);


	/* METHOD 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.
	 */
	} 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);
	    }

	    /* Open the image file if we can. */
	    if (fd = fopen (fname, "r")) {

		/* Seek to the offset specified. */
		lseek (fileno(fd), (off_t) hskip, SEEK_SET);

		/* Allocate the pixel pointer and read the data. */
		pix = (unsigned char *) malloc (nx * ny * (ABS(depth) / 8));
		fread (pix, ABS(depth)/8, nx * ny, fd);

		/* If we're zscaling and depth is more than 8-bits, do that. */
		if (zscale && ABS(depth) > 8) {
		    cdl_computeZscale (cdl, pix, nx, ny, depth, &z1, &z2);
		    cdl_zscaleImage (cdl, &pix, nx, ny, depth, z1, z2);
		}

		/* Select and clear the requested frame prior to display. */
	        cdl_setFrame (cdl, frame);
		cdl_clearFrame (cdl);

		/* Now 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 the WCS below.  
		 */
                cdl_selectFB (cdl, nx, ny, &fbconfig, &fb_w, &fb_h, &nf, 1);

		/* Compute the image placement so it's centered in the frame,
		 * but note the cdl_writeSubRaster() routine can place an
		 * arbitrary raster anywhere in the frame buffer.  
        	lx = (fb_w / 2) - (nx / 2);
        	ly = fb_h - ((fb_h / 2) + (ny / 2));

		/* Set the mapping we'll send with the WCS which must be
		 * called before the cdl_setWCS() call since the data is sent
		 * with the WCS and not as a separate call.
		 */

                /* First we must compose a node!path prefix for the image */
                gethostname (node, 512);
#ifdef SOLARIS
                (void) getcwd (path, 512);
#else
                (void) getwd (path);
#endif
                if (*fname == '/')
                    (void) sprintf (path_prefix, "%s!%s", node, fname);
                else
                    (void) sprintf (path_prefix, "%s!%s/%s", node, path, fname);

		cdl_setMapping (cdl, "image", 0., 0., nx, ny, lx, ly, nx, ny,
		    path_prefix);

		/* 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.
		 */
                cdl_setWCS (cdl, fname, "", 1., 0., 0., -1., 
                    (float) (nx / 2) - (fb_w / 2) + 1,	    /* X trans.     */
                    (float) (fb_h / 2) + (ny / 2),	    /* Y trans.     */
		    z1, z2, CDL_LINEAR);		    /* Z transform  */


		/* Now display the pixels.  
		 */
                if (cdl_writeSubRaster (cdl, lx, ly, nx, ny, pix))
                    status = 1;

		/* Now just free the pixel pointer to clean up.
		 */
		free ((unsigned char *) pix);
	        fclose (fd);

	    } 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;
	}
	
	cdl_close (cdl);			/* close the package */
	exit (status);
}