source: trunk/SRC/Picture/imdisp.pro @ 157

Last change on this file since 157 was 157, checked in by navarro, 18 years ago

header improvements + xxx doc

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