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

Last change on this file since 236 was 236, checked in by pinsard, 17 years ago

replace some print by some report in some .pro #2

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