source: trunk/SRC/ToBeReviewed/IMAGE/imdisp.pro @ 114

Last change on this file since 114 was 114, checked in by smasson, 18 years ago

new compilation options (compile_opt idl2, strictarrsubs) in each routine

  • Property svn:executable set to *
File size: 28.9 KB
Line 
1;-------------------------------------------------------------------------------
2FUNCTION IMDISP_GETPOS, ASPECT, POSITION=POSITION, MARGIN=MARGIN
3;
4  compile_opt idl2, strictarrsubs
5;
6
7;- Compute a position vector given an aspect ratio (called by IMDISP_IMSIZE)
8
9;- Check arguments
10if (n_params() ne 1) then message, 'Usage: RESULT = IMDISP_GETPOS(ASPECT)'
11if (n_elements(aspect) eq 0) then message, 'ASPECT is undefined'
12
13;- Check keywords
14if (n_elements(position) eq 0) then position = [0.0, 0.0, 1.0, 1.0]
15if (n_elements(margin) eq 0) then margin = 0.1
16
17;- Get range limited aspect ratio and margin input values
18aspect_val = (float(aspect[0]) > 0.01) < 100.0
19margin_val = (float(margin[0]) > 0.0) < 0.495
20
21;- Compute aspect ratio of position vector in this window
22xsize = (position[2] - position[0]) * !d.x_vsize
23ysize = (position[3] - position[1]) * !d.y_vsize
24cur_aspect = ysize / xsize
25
26;- Compute aspect ratio of this window
27win_aspect = float(!d.y_vsize) / float(!d.x_vsize)
28
29;- Compute height and width in normalized units
30if (aspect_val ge cur_aspect) then begin
31  height = (position[3] - position[1]) - 2.0 * margin
32  width  = height * (win_aspect / aspect_val)
33endif else begin
34  width  = (position[2] - position[0]) - 2.0 * margin
35  height = width * (aspect_val / win_aspect)
36endelse
37
38;- Compute and return position vector
39xcenter = 0.5 * (position[0] + position[2])
40ycenter = 0.5 * (position[1] + position[3])
41x0 = xcenter - 0.5 * width
42y0 = ycenter - 0.5 * height
43x1 = xcenter + 0.5 * width
44y1 = ycenter + 0.5 * height
45return, [x0, y0, x1, y1]
46
47END
48;-------------------------------------------------------------------------------
49FUNCTION IMDISP_IMSCALE, IMAGE, RANGE=RANGE, BOTTOM=BOTTOM, NCOLORS=NCOLORS, $
50  NEGATIVE=NEGATIVE
51;
52  compile_opt idl2, strictarrsubs
53;
54
55;- Byte-scale an image (called by IMDISP)
56
57;- Check arguments
58if (n_params() ne 1) then message, 'Usage: RESULT = IMDISP_IMSCALE(IMAGE)'
59if (n_elements(image) eq 0) then message, 'Argument IMAGE is undefined'
60
61;- Check keywords
62if (n_elements(range) eq 0) then begin
63  min_value = min(image, max=max_value)
64  range = [min_value, max_value]
65endif
66if (n_elements(bottom) eq 0) then bottom = 0B
67if (n_elements(ncolors) eq 0) then ncolors = !d.table_size - bottom
68
69;- Compute the scaled image
70scaled = bytscl(image, min=range[0], max=range[1], top=(ncolors - 1))
71
72;- Create a negative image if required
73if keyword_set(negative) then scaled = byte(ncolors - 1) - scaled
74
75;- Return the scaled image in the correct color range
76return, scaled + byte(bottom)
77
78END
79;-------------------------------------------------------------------------------
80FUNCTION IMDISP_IMREGRID, DATA, NX, NY, INTERP=INTERP
81;
82  compile_opt idl2, strictarrsubs
83;
84
85;- Regrid a 2D array (called by IMDISP)
86
87;- Check arguments
88if (n_params() ne 3) then $
89  message, 'Usage: RESULT = IMDISP_IMREGRID(DATA, NX, NY)'
90if (n_elements(data) eq 0) then message, 'Argument DATA is undefined'
91result = size(data)
92ndims = result[0]
93dims = result[1:ndims]
94if (ndims ne 2) then message, 'Argument DATA must have 2 dimensions'
95if (n_elements(nx) eq 0) then message, 'Argument NX is undefined'
96if (n_elements(ny) eq 0) then message, 'Argument NY is undefined'
97if (nx lt 1) then message, 'NX must be 1 or greater'
98if (ny lt 1) then message, 'NY must be 1 or greater'
99
100;- Copy the array if the requested size is the same as the current size
101if (nx eq dims[0]) and (ny eq dims[1]) then begin
102  new = data
103  return, new
104endif
105
106;- Compute index arrays for bilinear interpolation
107xindex = (findgen(nx) + 0.5) * (dims[0] / float(nx)) - 0.5
108yindex = (findgen(ny) + 0.5) * (dims[1] / float(ny)) - 0.5
109
110;- Round the index arrays if nearest neighbor sampling is required
111if (keyword_set(interp) eq 0) then begin
112  xindex = round(xindex)
113  yindex = round(yindex)
114endif
115
116;- Return regridded array
117return, interpolate(data, xindex, yindex, /grid)
118
119END
120;-------------------------------------------------------------------------------
121PRO IMDISP_IMSIZE, IMAGE, X0, Y0, XSIZE, YSIZE, ASPECT=ASPECT, $
122  POSITION=POSITION, MARGIN=MARGIN
123;
124  compile_opt idl2, strictarrsubs
125;
126
127;- Compute the size and offset for an image (called by IMDISP)
128
129;- Check arguments
130if (n_params() ne 5) then $
131  message, 'Usage: IMDISP_IMSIZE, IMAGE, X0, Y0, XSIZE, YSIZE'
132if (n_elements(image) eq 0) then $
133  message, 'Argument IMAGE is undefined'
134if (n_elements(position) eq 0) then position = [0.0, 0.0, 1.0, 1.0]
135if (n_elements(position) ne 4) then $
136  message, 'POSITION must be a 4 element vector'
137if (n_elements(margin) eq 0) then margin = 0.1
138if (n_elements(margin) ne 1) then $
139  message, 'MARGIN must be a scalar'
140
141;- Get image dimensions
142result = size(image)
143ndims = result[0]
144if (ndims ne 2) then message, 'IMAGE must be a 2D array'
145dims = result[1 : ndims]
146
147;- Get aspect ratio for image
148if (n_elements(aspect) eq 0) then $
149  aspect = float(dims[1]) / float(dims[0])
150if (n_elements(aspect) ne 1) then $
151  message, 'ASPECT must be a scalar'
152
153;- Check output parameters
154if (arg_present(x0) ne 1) then message, 'Argument XO cannot be set'
155if (arg_present(y0) ne 1) then message, 'Argument YO cannot be set'
156if (arg_present(xsize) ne 1) then message, 'Argument XSIZE cannot be set'
157if (arg_present(ysize) ne 1) then message, 'Argument YSIZE cannot be set'
158
159;- Get approximate image position
160position = imdisp_getpos(aspect, position=position, margin=margin)
161
162;- Compute lower left position of image (device units)
163x0 = round(position[0] * !d.x_vsize) > 0L
164y0 = round(position[1] * !d.y_vsize) > 0L
165
166;- Compute size of image (device units)
167xsize = round((position[2] - position[0]) * !d.x_vsize) > 2L
168ysize = round((position[3] - position[1]) * !d.y_vsize) > 2L
169
170;- Recompute the image position based on actual image size
171position = fltarr(4)
172position[0] = x0 / float(!d.x_vsize)
173position[1] = y0 / float(!d.y_vsize)
174position[2] = (x0 + xsize) / float(!d.x_vsize)
175position[3] = (y0 + ysize) / float(!d.y_vsize)
176
177END
178;-------------------------------------------------------------------------------
179PRO IMDISP, IMAGE, RANGE=RANGE, BOTTOM=BOTTOM, NCOLORS=NCOLORS, $
180  MARGIN=MARGIN, INTERP=INTERP, DITHER=DITHER, ASPECT=ASPECT, $
181  POSITION=POSITION, OUT_POS=OUT_POS, NOSCALE=NOSCALE, NORESIZE=NORESIZE, $
182  ORDER=ORDER, USEPOS=USEPOS, CHANNEL=CHANNEL, $
183  BACKGROUND=BACKGROUND, ERASE=ERASE, $
184  AXIS=AXIS, NEGATIVE=NEGATIVE, _EXTRA=EXTRA_KEYWORDS
185;
186  compile_opt idl2, strictarrsubs
187;
188
189;+
190; NAME:
191;    IMDISP
192;
193; PURPOSE:
194;    Display an image on the current graphics device.
195;    IMDISP is an advanced replacement for TV and TVSCL.
196;
197;    - Supports WIN, MAC, X, CGM, PCL, PRINTER, PS, and Z graphics devices,
198;    - Image is automatically byte-scaled (can be disabled),
199;    - Custom byte-scaling of Pseudo color images via the RANGE keyword,
200;    - Pseudo (indexed) color and True color images are handled automatically,
201;    - 8-bit and 24-bit graphics devices  are handled automatically,
202;    - Decomposed color settings are handled automatically,
203;    - Image is automatically sized to fit the display (can be disabled),
204;    - The !P.MULTI system variable is honored for multiple image display,
205;    - Image can be positioned via the POSITION keyword,
206;    - Color table splitting via the BOTTOM and NCOLORS keywords,
207;    - Image aspect ratio customization via the ASPECT keyword,
208;    - Resized images can be resampled (default) or interpolated,
209;    - Top down image display via the ORDER keyword (!ORDER is ignored),
210;    - Selectable display channel (R/G/B) via the CHANNEL keyword,
211;    - Background can be set to a specified color via the BACKGROUND keyword,
212;    - Screen can be erased prior to image display via the ERASE keyword,
213;    - Plot axes can be drawn on the image via the AXIS keyword,
214;    - Photographic negative images can be displayed via the NEGATIVE keyword.
215;
216; CATEGORY:
217;    Image display
218;
219; CALLING SEQUENCE:
220;    IMDISP, IMAGE
221;
222; INPUTS:
223;    IMAGE       Array containing image data.
224;                Pseudo (indexed) color images must have 2 dimensions.
225;                True color images must have 3 dimensions, in either
226;                [3, NX, NY], [NX, 3, NY], or [NX, NY, 3] form.
227;
228; OPTIONAL INPUTS:
229;    None.
230;
231; KEYWORD PARAMETERS:
232;    RANGE       For Pseudo Color images only, a vector with two elements
233;                specifying the minimum and maximum values of the image
234;                array to be considered when the image is byte-scaled
235;                (default is minimum and maximum array values).
236;                This keyword is ignored for True Color images,
237;                or if the NOSCALE keyword is set.
238;
239;    BOTTOM      Bottom value in the color table to be used
240;                for the byte-scaled image
241;                (default is 0).
242;                This keyword is ignored if the NOSCALE keyword is set.
243;
244;    NCOLORS     Number of colors in the color table to be used
245;                for the byte-scaled image
246;                (default is !D.TABLE_SIZE - BOTTOM).
247;                This keyword is ignored if the NOSCALE keyword is set.
248;
249;    MARGIN      A scalar value specifying the margin to be maintained
250;                around the image in normal coordinates
251;                (default is 0.1, or 0.025 if !P.MULTI is set to display
252;                multiple images).
253;
254;    INTERP      If set, the resized image will be interpolated using
255;                bilinear interpolation
256;                (default is nearest neighbor sampling).
257;
258;    DITHER      If set, true color images will be dithered when displayed
259;                on an 8-bit graphics device
260;                (default is no dithering).
261;
262;    ASPECT      A scalar value specifying the aspect ratio (height/width)
263;                for the displayed image
264;                (default is to maintain native aspect ratio).
265;
266;    POSITION    On input, a 4-element vector specifying the position
267;                of the displayed image in the form [X0,Y0,X1,Y1] in
268;                in normal coordinates
269;                (default is [0.0,0.0,1.0,1.0]).
270;                See the examples below to display an image where only the
271;                offset and size are known (e.g. MAP_IMAGE output).
272;
273;    OUT_POS     On output, a 4-element vector specifying the position
274;                actually used to display the image.
275;
276;    NOSCALE     If set, the image will not be byte-scaled
277;                (default is to byte-scale the image).
278;
279;    NORESIZE    If set, the image will not be resized.
280;                (default is to resize the image to fit the display).
281;
282;    ORDER       If set, the image is displayed from the top down
283;                (default is to display the image from the bottom up).
284;                Note that the system variable !ORDER is always ignored.
285;
286;    USEPOS      If set, the image will be sized to exactly fit a supplied
287;                POSITION vector, over-riding ASPECT and MARGIN
288;                (default is to honor ASPECT and MARGIN when a POSITION
289;                vector is supplied).
290;
291;    CHANNEL     Display channel (Red, Green, or Blue) to be written.
292;                0 => All channels (the default)
293;                1 => Red channel
294;                2 => Green channel
295;                3 => Blue channel
296;                This keyword is only recognized by graphics devices which
297;                support 24-bit decomposed color (WIN, MAC, X). It is ignored
298;                by all other graphics devices. However True color (RGB)
299;                images can be displayed on any device supported by IMDISP.
300;
301;    BACKGROUND  If set to a positive integer, the background will be filled
302;                with the color defined by BACKGROUND.
303;
304;    ERASE       If set, the screen contents will be erased. Note that if
305;                !P.MULTI is set to display multiple images, the screen is
306;                always erased when the first image is displayed.
307;
308;    AXIS        If set, plot axes will be drawn on the image. The default
309;                x and y axis ranges are determined by the size of the image.
310;                When the AXIS keyword is set, IMDISP accepts any keywords
311;                supported by PLOT (e.g. TITLE, COLOR, CHARSIZE etc.).
312;
313;    NEGATIVE    If set, a photographic negative of the image is displayed.
314;                The values of BOTTOM and NCOLORS are honored. This keyword
315;                allows True color images scanned from color negatives to be
316;                displayed. It also allows Pseudo color images to be displayed
317;                as negatives without reversing the color table. This keyword
318;                is ignored if the NOSCALE keyword is set.
319;
320; OUTPUTS:
321;    None.
322;
323; OPTIONAL OUTPUTS:
324;    None
325;
326; COMMON BLOCKS:
327;    None
328;
329; SIDE EFFECTS:
330;    The image is displayed on the current graphics device.
331;
332; RESTRICTIONS:
333;    Requires IDL 5.0 or higher (square bracket array syntax).
334;
335; EXAMPLE:
336;
337;;- Load test data
338;
339;openr, lun, filepath('ctscan.dat', subdir='examples/data'), /get_lun
340;ctscan = bytarr(256, 256)
341;readu, lun, ctscan
342;free_lun, lun
343;openr, lun, filepath('hurric.dat', subdir='examples/data'), /get_lun
344;hurric = bytarr(440, 330)
345;readu, lun, hurric
346;free_lun, lun
347;read_jpeg, filepath('rose.jpg', subdir='examples/data'), rose
348;help, ctscan, hurric, rose
349;
350;;- Display single images
351;
352;!p.multi = 0
353;loadct, 0
354;imdisp, hurric, /erase
355;wait, 3.0
356;imdisp, rose, /interp, /erase
357;wait, 3.0
358;
359;;- Display multiple images without color table splitting
360;;- (works on 24-bit displays only; top 2 images are garbled on 8-bit displays)
361;
362;!p.multi = [0, 1, 3, 0, 0]
363;loadct, 0
364;imdisp, ctscan, margin=0.02
365;loadct, 13
366;imdisp, hurric, margin=0.02
367;imdisp, rose, margin=0.02
368;wait, 3.0
369;
370;;- Display multiple images with color table splitting
371;;- (works on 8-bit or 24-bit displays)
372;
373;!p.multi = [0, 1, 3, 0, 0]
374;loadct, 0, ncolors=64, bottom=0
375;imdisp, ctscan, margin=0.02, ncolors=64, bottom=0
376;loadct, 13, ncolors=64, bottom=64
377;imdisp, hurric, margin=0.02, ncolors=64, bottom=64
378;imdisp, rose, margin=0.02, ncolors=64, bottom=128
379;wait, 3.0
380;
381;;- Display an image at a specific position, over-riding aspect and margin
382;
383;!p.multi = 0
384;loadct, 0
385;imdisp, hurric, position=[0.0, 0.0, 1.0, 0.5], /usepos, /erase
386;wait, 3.0
387;
388;;- Display an image with axis overlay
389;
390;!p.multi = 0
391;loadct, 0
392;imdisp, rose, /axis, /erase
393;wait, 3.0
394;
395;;- Display an image with contour plot overlay
396;
397;!p.multi = 0
398;loadct, 0
399;imdisp, hurric, out_pos=out_pos, /erase
400;contour, smooth(hurric, 10, /edge), /noerase, position=out_pos, $
401;  xstyle=1, ystyle=1, levels=findgen(5)*40.0, /follow
402;wait, 3.0
403;
404;;- Display a small image with correct resizing
405;
406;!p.multi = 0
407;loadct, 0
408;data = (dist(8))[1:7, 1:7]
409;imdisp, data, /erase
410;wait, 3.0
411;imdisp, data, /interp
412;wait, 3.0
413;
414;;- Display a true color image without and with interpolation
415;
416;!p.multi = 0
417;imdisp, rose, /erase
418;wait, 3.0
419;imdisp, rose, /interp
420;wait, 3.0
421;
422;;- Display a true color image as a photographic negative
423;
424;imdisp, rose, /negative, /erase
425;wait, 3.0
426;
427;;- Display a true color image on PostScript output
428;;- (note that color table is handled automatically)
429;
430;current_device = !d.name
431;set_plot, 'PS'
432;device, /color, bits_per_pixel=8, filename='imdisp_true.ps'
433;imdisp, rose, /axis, title='PostScript True Color Output'
434;device, /close
435;set_plot, current_device
436;
437;;- Display a pseudo color image on PostScript output
438;
439;current_device = !d.name
440;set_plot, 'PS'
441;device, /color, bits_per_pixel=8, filename='imdisp_pseudo.ps'
442;loadct, 0
443;imdisp, hurric, /axis, title='PostScript Pseudo Color Output'
444;device, /close
445;set_plot, current_device
446;
447;;- Display an image where only the offset and size are known
448;
449;;- Read world elevation data
450;file = filepath('worldelv.dat', subdir='examples/data')
451;openr, lun, file, /get_lun
452;data = bytarr(360, 360)
453;readu, lun, data
454;free_lun, lun
455;;- Reorganize array so it spans 180W to 180E
456;world = data
457;world[0:179, *] = data[180:*, *]
458;world[180:*, *] = data[0:179, *]
459;;- Create remapped image
460;map_set, /orthographic, /isotropic, /noborder
461;remap = map_image(world, x0, y0, xsize, ysize, compress=1)
462;;- Convert offset and size to position vector
463;pos = fltarr(4)
464;pos[0] = x0 / float(!d.x_vsize)
465;pos[1] = y0 / float(!d.y_vsize)
466;pos[2] = (x0 + xsize) / float(!d.x_vsize)
467;pos[3] = (y0 + ysize) / float(!d.y_vsize)
468;;- Display the image
469;loadct, 0
470;imdisp, remap, pos=pos, /usepos
471;map_continents
472;map_grid
473;
474; MODIFICATION HISTORY:
475; Liam.Gumley@ssec.wisc.edu
476; http://cimss.ssec.wisc.edu/~gumley
477; $Id: imdisp.pro,v 1.47 2002/06/05 16:31:07 gumley Exp $
478;
479; Copyright (C) 1999, 2000 Liam E. Gumley
480;
481; This program is free software; you can redistribute it and/or
482; modify it under the terms of the GNU General Public License
483; as published by the Free Software Foundation; either version 2
484; of the License, or (at your option) any later version.
485;
486; This program is distributed in the hope that it will be useful,
487; but WITHOUT ANY WARRANTY; without even the implied warranty of
488; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
489; GNU General Public License for more details.
490;
491; You should have received a copy of the GNU General Public License
492; along with this program; if not, write to the Free Software
493; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
494;-
495
496rcs_id = '$Id: imdisp.pro,v 1.47 2002/06/05 16:31:07 gumley Exp $'
497
498;-------------------------------------------------------------------------------
499;- CHECK INPUT
500;-------------------------------------------------------------------------------
501
502;- Check arguments
503if (n_params() ne 1) then message, 'Usage: IMDISP, IMAGE'
504if (n_elements(image) eq 0) then message, 'Argument IMAGE is undefined'
505if (max(!p.multi) eq 0) then begin
506  if (n_elements(margin) eq 0) then begin
507    if (n_elements(position) eq 4) then margin = 0.0 else margin = 0.1
508  endif
509endif else begin
510  if (n_elements(margin) eq 0) then margin = 0.025
511endelse
512if (n_elements(order) eq 0) then order = 0
513if (n_elements(channel) eq 0) then channel = 0
514
515;- Check position vector
516if (n_elements(position) gt 0) then begin
517  if (n_elements(position) ne 4) then $
518    message, 'POSITION must be a 4 element vector of the form [X0, Y0, X1, Y1]'
519  if (position[0] lt 0.0) then message, 'POSITION[0] must be GE 0.0'
520  if (position[1] lt 0.0) then message, 'POSITION[1] must be GE 0.0'
521  if (position[2] gt 1.0) then message, 'POSITION[2] must be LE 1.0'
522  if (position[3] gt 1.0) then message, 'POSITION[3] must be LE 1.0'
523  if (position[0] ge position[2]) then $
524    message, 'POSITION[0] must be LT POSITION[2]'
525  if (position[1] ge position[3]) then $
526    message, 'POSITION[1] must be LT POSITION[3]'
527endif
528
529;- Check the image dimensions
530result = size(image)
531ndims = result[0]
532if (ndims lt 2) or (ndims gt 3) then $
533  message, 'IMAGE must be a Pseudo Color (2D) or True Color (3D) image array'
534dims = result[1:ndims]
535
536;- Check that 3D image array is in valid true color format
537true = 0
538if (ndims eq 3) then begin
539  index = where(dims eq 3L, count)
540  if (count eq 0) then $
541    message, 'True Color dimensions must be [3,NX,NY], [NX,3,NY], or [NX,NY,3]'
542  true = 1
543  truedim = index[0]
544endif
545
546;- Check scaling range for pseudo color images
547if (true eq 0) then begin
548  if (n_elements(range) eq 0) then begin
549    min_value = min(image, max=max_value)
550    range = [min_value, max_value]
551  endif
552  if (n_elements(range) ne 2) then $
553    message, 'RANGE keyword must be a 2-element vector'
554endif else begin
555  if (n_elements(range) gt 0) then $
556    message, 'RANGE keyword is not used for True Color images', /continue
557endelse
558
559;- Check for supported graphics devices
560names = ['WIN', 'MAC', 'X', 'CGM', 'PCL', 'PRINTER', 'PS', 'Z']
561result = where((!d.name eq names), count)
562if (count eq 0) then message, 'Graphics device is not supported'
563
564;- Get color table information
565if ((!d.flags and 256) ne 0) and (!d.window lt 0) then begin
566  window, /free, /pixmap
567  wdelete, !d.window
568endif
569if (n_elements(bottom) eq 0) then bottom = 0
570if (n_elements(ncolors) eq 0) then ncolors = !d.table_size - bottom
571
572;- Get IDL version number
573version = float(!version.release)
574
575;- Check for IDL 5.2 or higher if printer device is selected
576if (version lt 5.2) and (!d.name eq 'PRINTER') then $
577  message, 'IDL 5.2 or higher is required for PRINTER device support'
578
579;-------------------------------------------------------------------------------
580;- GET RED, GREEN, AND BLUE COMPONENTS OF TRUE COLOR IMAGE
581;-------------------------------------------------------------------------------
582
583if (true eq 1) then begin
584    case truedim of
585      0 : begin
586            red = image[0, *, *]
587            grn = image[1, *, *]
588            blu = image[2, *, *]
589      end
590      1 : begin
591            red = image[*, 0, *]
592            grn = image[*, 1, *]
593            blu = image[*, 2, *]
594      end
595      2 : begin
596            red = image[*, *, 0]
597            grn = image[*, *, 1]
598            blu = image[*, *, 2]
599      end
600  endcase
601  red = reform(red, /overwrite)
602  grn = reform(grn, /overwrite)
603  blu = reform(blu, /overwrite)
604endif
605
606;-------------------------------------------------------------------------------
607;- COMPUTE POSITION FOR IMAGE
608;-------------------------------------------------------------------------------
609
610;- Save first element of !p.multi
611multi_first = !p.multi[0]
612
613;- Establish image position if not defined
614if (n_elements(position) eq 0) then begin
615  if (max(!p.multi) eq 0) then begin
616    position = [0.0, 0.0, 1.0, 1.0]
617  endif else begin
618    plot, [0], /nodata, xstyle=4, ystyle=4, xmargin=[0, 0], ymargin=[0, 0]
619    position = [!x.window[0], !y.window[0], !x.window[1], !y.window[1]]
620  endelse
621endif
622
623;- Erase and fill the background if required
624if (multi_first eq 0) then begin
625  if keyword_set(erase) then erase
626  if (n_elements(background) gt 0) then begin
627    polyfill, [-0.01,  1.01,  1.01, -0.01, -0.01], $
628      [-0.01, -0.01,  1.01,  1.01, -0.01], /normal, color=background[0]
629  endif
630endif
631
632;- Compute image aspect ratio if not defined
633if (n_elements(aspect) eq 0) then begin
634  case true of
635    0 : result = size(image)
636    1 : result = size(red)
637  endcase
638  dims = result[1:2]
639  aspect = float(dims[1]) / float(dims[0])
640endif
641
642;- Save image xrange and yrange for axis overlays
643xrange = [0, dims[0]]
644yrange = [0, dims[1]]
645if (order eq 1) then yrange = reverse(yrange)
646
647;- Set the aspect ratio and margin to fill the position window if requested
648if keyword_set(usepos) then begin
649  xpos_size = float(!d.x_vsize) * (position[2] - position[0])
650  ypos_size = float(!d.y_vsize) * (position[3] - position[1])
651  aspect_value = ypos_size / xpos_size
652  margin_value = 0.0
653endif else begin
654  aspect_value = aspect
655  margin_value = margin
656endelse
657
658;- Compute size of displayed image and save output position
659pos = position
660case true of
661  0 : imdisp_imsize, image, x0, y0, xsize, ysize, position=pos, $
662        aspect=aspect_value, margin=margin_value
663  1 : imdisp_imsize,   red, x0, y0, xsize, ysize, position=pos, $
664        aspect=aspect_value, margin=margin_value
665endcase
666out_pos = pos
667
668;-------------------------------------------------------------------------------
669;- BYTE-SCALE THE IMAGE IF REQUIRED
670;-------------------------------------------------------------------------------
671
672;- Choose whether to scale the image or not
673if (keyword_set(noscale) eq 0) then begin
674
675  ;- Scale the image
676  case true of
677    0 : scaled = imdisp_imscale(image, bottom=bottom, ncolors=ncolors, $
678          range=range, negative=keyword_set(negative))
679    1 : begin
680          scaled_dims = (size(red))[1:2]
681          scaled = bytarr(scaled_dims[0], scaled_dims[1], 3)
682          scaled[0, 0, 0] = imdisp_imscale(red, bottom=0, ncolors=256, $
683            negative=keyword_set(negative))
684          scaled[0, 0, 1] = imdisp_imscale(grn, bottom=0, ncolors=256, $
685            negative=keyword_set(negative))
686          scaled[0, 0, 2] = imdisp_imscale(blu, bottom=0, ncolors=256, $
687            negative=keyword_set(negative))
688        end
689  endcase
690
691endif else begin
692
693  ;- Don't scale the image
694  case true of
695    0 : scaled = image
696    1 : begin
697          scaled_dims = (size(red))[1:2]
698          scaled = replicate(red[0], scaled_dims[0], scaled_dims[1], 3)
699          scaled[0, 0, 0] = red
700          scaled[0, 0, 1] = grn
701          scaled[0, 0, 2] = blu
702        end
703  endcase
704
705endelse
706
707;-------------------------------------------------------------------------------
708;- DISPLAY IMAGE ON PRINTER DEVICE
709;-------------------------------------------------------------------------------
710
711if (!d.name eq 'PRINTER') then begin
712
713  ;- Display the image
714  case true of
715    0 : begin
716          device, /index_color
717          tv, scaled, x0, y0, xsize=xsize, ysize=ysize, order=order
718        end
719    1 : begin
720          device, /true_color
721          tv, scaled, x0, y0, xsize=xsize, ysize=ysize, order=order, true=3
722        end
723  endcase
724
725  ;- Draw axes if required
726  if keyword_set(axis) then $
727    plot, [0], /nodata, /noerase, position=out_pos, $
728      xrange=xrange, xstyle=1, yrange=yrange, ystyle=1, $
729      _extra=extra_keywords
730
731  ;- Return to caller
732  return
733
734endif
735
736;-------------------------------------------------------------------------------
737;- DISPLAY IMAGE ON GRAPHICS DEVICES WHICH HAVE SCALEABLE PIXELS
738;-------------------------------------------------------------------------------
739
740if ((!d.flags and 1) ne 0) then begin
741
742  ;- Display the image
743  case true of
744    0 : tv, scaled, x0, y0, xsize=xsize, ysize=ysize, order=order
745    1 : begin
746          tvlct, r, g, b, /get
747          loadct, 0, /silent
748          tv, scaled, x0, y0, xsize=xsize, ysize=ysize, order=order, true=3
749          tvlct, r, g, b
750        end
751  endcase
752
753  ;- Draw axes if required
754  if keyword_set(axis) then $
755    plot, [0], /nodata, /noerase, position=out_pos, $
756      xrange=xrange, xstyle=1, yrange=yrange, ystyle=1, $
757      _extra=extra_keywords
758
759  ;- Return to caller
760  return
761
762endif
763
764;-------------------------------------------------------------------------------
765;- RESIZE THE IMAGE
766;-------------------------------------------------------------------------------
767
768;- Resize the image
769if (keyword_set(noresize) eq 0) then begin
770  if (true eq 0) then begin
771    resized = imdisp_imregrid(scaled, xsize, ysize, interp=keyword_set(interp))
772  endif else begin
773    resized = replicate(scaled[0], xsize, ysize, 3)
774    resized[0, 0, 0] = imdisp_imregrid(reform(scaled[*, *, 0]), xsize, ysize, $
775      interp=keyword_set(interp))
776    resized[0, 0, 1] = imdisp_imregrid(reform(scaled[*, *, 1]), xsize, ysize, $
777      interp=keyword_set(interp))
778    resized[0, 0, 2] = imdisp_imregrid(reform(scaled[*, *, 2]), xsize, ysize, $
779      interp=keyword_set(interp))
780  endelse
781endif else begin
782  resized = temporary(scaled)
783  x0 = 0
784  y0 = 0
785endelse
786
787;-------------------------------------------------------------------------------
788;- GET BIT DEPTH FOR THIS DISPLAY
789;-------------------------------------------------------------------------------
790
791;- If this device supports windows, make sure a window has been opened
792if (!d.flags and 256) ne 0 then begin
793  if (!d.window lt 0) then begin
794    window, /free, /pixmap
795    wdelete, !d.window
796  endif
797endif
798
799;- Set default display depth
800depth = 8
801
802;- Get actual bit depth on supported displays
803if (!d.name eq 'WIN') or (!d.name eq 'MAC') or (!d.name eq 'X') then begin
804  if (version ge 5.1) then begin
805    device, get_visual_depth=depth
806  endif else begin
807    if (!d.n_colors gt 256) then depth = 24
808  endelse
809endif
810
811;-------------------------------------------------------------------------------
812;- SELECT DECOMPOSED COLOR MODE (ON OR OFF) FOR 24-BIT DISPLAYS
813;-------------------------------------------------------------------------------
814
815if (!d.name eq 'WIN') or (!d.name eq 'MAC') or (!d.name eq 'X') then begin
816  if (depth gt 8) then begin
817    if (version ge 5.2) then device, get_decomposed=entry_decomposed else $
818      entry_decomposed = 0
819    if (true eq 1) or (channel gt 0) then device, decomposed=1 else $
820      device, decomposed=0
821  endif
822endif
823
824;-------------------------------------------------------------------------------
825;- DISPLAY THE IMAGE
826;-------------------------------------------------------------------------------
827
828;- If the display is 8-bit and the image is true color,
829;- convert image from true color to indexed color
830if (depth le 8) and (true eq 1) then begin
831  resized = color_quan(temporary(resized), 3, r, g, b, $
832    colors=ncolors, dither=keyword_set(dither)) + byte(bottom)
833  tvlct, r, g, b, bottom
834  true = 0
835endif
836
837;- Set channel value for supported devices
838if (!d.name eq 'WIN') or (!d.name eq 'MAC') or (!d.name eq 'X') then begin
839  channel_value = channel
840endif else begin
841  channel_value = 0
842endelse
843
844;- Display the image
845case true of
846  0 : tv, resized, x0, y0, order=order, channel=channel_value
847  1 : tv, resized, x0, y0, order=order, true=3
848endcase
849
850;-------------------------------------------------------------------------------
851;- RESTORE THE DECOMPOSED COLOR MODE FOR 24-BIT DISPLAYS
852;-------------------------------------------------------------------------------
853
854if ((!d.name eq 'WIN') or (!d.name eq 'MAC') or (!d.name eq 'X')) and $
855  (depth gt 8) then begin
856  device, decomposed=entry_decomposed
857  if (!d.name eq 'MAC') then tv, [0], -1, -1
858endif
859
860;-------------------------------------------------------------------------------
861;- DRAW AXES IF REQUIRED
862;-------------------------------------------------------------------------------
863
864if keyword_set(axis) then $
865  plot, [0], /nodata, /noerase, position=out_pos, $
866    xrange=xrange, xstyle=1, yrange=yrange, ystyle=1, $
867    _extra=extra_keywords
868
869END
Note: See TracBrowser for help on using the repository browser.