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

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

improvements/corrections of some *.pro headers

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