source: trunk/MESOSCALE_DEV/PLOT/MINIMAL/fsc/tvimage.pro @ 207

Last change on this file since 207 was 85, checked in by aslmd, 14 years ago

LMD_MM_MARS et LMD_LES_MARS: ajout des routines IDL pour tracer les sorties --> voir mesoscale/PLOT

File size: 45.6 KB
Line 
1;+
2; NAME:
3;     TVIMAGE
4;
5; PURPOSE:
6;     This purpose of TVIMAGE is to enable the TV command in IDL
7;     to be a completely device-independent and color-decomposition-
8;     state independent command. On 24-bit displays color decomposition
9;     is always turned off for 8-bit images and on for 24-bit images.
10;     The color decomposition state is restored for those versions of
11;     IDL that support it (> 5.2). Moreover, TVIMAGE adds features
12;     that TV lacks. For example, images can be positioned in windows
13;     using the POSITION keyword like other IDL graphics commands.
14;     TVIMAGE also supports the !P.MULTI system variable, unlike the
15;     TV command. TVIMAGE was written to work especially well in
16;     resizeable graphics windows. Note that if you wish to preserve
17;     the aspect ratio of images in resizeable windows, you should set
18;     the KEEP_ASPECT_RATIO keyword, described below. TVIMAGE works
19;     equally well on the display, in the PostScript device, and in
20;     the Printer and Z-Graphics Buffer devices. The TRUE keyword is
21;     set automatically to the correct value for 24-bit images, so you
22;     don't need to specify it when using TVIMAGE.
23;
24; AUTHOR:
25;       FANNING SOFTWARE CONSULTING:
26;       David Fanning, Ph.D.
27;       1645 Sheely Drive
28;       Fort Collins, CO 80526 USA
29;       Phone: 970-221-0438
30;       E-mail: davidf@dfanning.com
31;       Coyote's Guide to IDL Programming: http://www.dfanning.com/
32;
33; CATEGORY:
34;     Graphics display.
35;
36; CALLING SEQUENCE:
37;
38;     TVIMAGE, image
39;
40; INPUTS:
41;     image:    A 2D or 3D image array. It should be byte data.
42;
43;       x  :    The X position of the lower-left corner of the image.
44;               This parameter is only recognized if the TV keyword is set.
45;               If the Y position is not used, X is taken to be the image
46;               "position" in the window. See the TV command documenation
47;               for details.
48;
49;       y  :    The Y position of the lower-left corner of the image.
50;               This parameter is only recognized if the TV keyword is set.
51;
52; KEYWORD PARAMETERS:
53;
54;     ACOLOR:   Set this keyword to the axis color. If a byte or integer value,
55;               it will assume you are using INDEXED color mode. If a long integer
56;               is will assume you are using DECOMPOSED color mode. If a string,
57;               is will pass the string color name along to FSC_COLOR for processing.
58;
59;     AXES:     Set this keyword to draw a set of axes around the image.
60;
61;     AXKEYWORDS:   An IDL structure variable of PLOT keywords as structure fields
62;               and keyword values as the values of the fields. Pass directly to the
63;               PLOT command that draws the axes for the image. Ignored unless the
64;               AXES keyword is set. For example,
65;
66;               TVImage, image, /AXES, AXKEYWORDS={CHARSIZE:1.5, XTITLE:'Distance (mm)', $
67;                    YTITLE:'Signal', TICKLEN:-0.025}, ACOLOR='NAVY'
68;
69;     BACKGROUND:   This keyword specifies the background color. Note that
70;               the keyword ONLY has effect if the ERASE keyword is also
71;               set or !P.MULTI is set to multiple plots and TVIMAGE is
72;               used to place the *first* plot. Can be a string (e.g., 'ivory'), or
73;               a 24-bit value that can be decomposed into a color, or an 8-bit
74;               index number into the current color table. ERASE and BACKGROUND
75;               should only be used on 24-bit devices that support windows!
76;
77;     BREWER:   If set, applies only to BACKGROUND AND ACOLOR keywords. Selects
78;               brewer colors, rather than standard FSC_COLOR colors as strings.
79;
80;     ERASE:    If this keyword is set an ERASE command is issued
81;               before the image is displayed. ERASE and BACKGROUND
82;               should only be used on 24-bit devices that support windows!
83;               The keyword is ignored on 8-bit devices or devices that do
84;               not support windows.
85;
86;     _EXTRA:   This keyword picks up any TV keywords you wish to use.
87;
88;     HALF_HALF: If set, will tell CONGRID to extrapolate a *half* row
89;               and column on either side, rather than the default of
90;               one full row/column at the ends of the array.  If you
91;               are interpolating images with few rows, then the
92;               output will be more consistent with this technique.
93;               This keyword is intended as a replacement for
94;               MINUS_ONE, and both keywords probably should not be
95;               used in the same call to CONGRID.
96;
97;     KEEP_ASPECT_RATIO: Normally, the image will be resized to fit the
98;               specified position in the window. If you prefer, you can
99;               force the image to maintain its aspect ratio in the window
100;               (although not its natural size) by setting this keyword.
101;               The image width is fitted first. If, after setting the
102;               image width, the image height is too big for the window,
103;               then the image height is fitted into the window. The
104;               appropriate values of the POSITION keyword are honored
105;               during this fitting process. Once a fit is made, the
106;               POSITION coordiates are re-calculated to center the image
107;               in the window. You can recover these new position coordinates
108;               as the output from the POSITION keyword.
109;
110;     MARGIN:   A single value, expressed as a normalized coordinate, that
111;               can easily be used to calculate a position in the window.
112;               The margin is used to calculate a POSITION that gives
113;               the image an equal margin around the edge of the window.
114;               The margin must be a number in the range 0.0 to 0.333. This
115;               keyword is ignored if the POSITION or OVERPLOT keywords are
116;               used. It is also ignored when TVImage is executed in a
117;               multi-plot window, EXCEPT if it's value is zero. In this
118;               special case, the image will be drawn into its position in
119;               the multi-plot window with no margins whatsoever. (The
120;               default is to have a slight margin about the image to separate
121;               it from other images or graphics.
122;
123;     MINUS_ONE: The value of this keyword is passed along to the CONGRID
124;               command. It prevents CONGRID from adding an extra row and
125;               column to the resulting array, which can be a problem with
126;               small image arrays.
127;
128;     NOINTERPOLATION: Setting this keyword disables the default bilinear
129;               interpolation done to the image when it is resized. Nearest
130;               neighbor interpolation is done instead. This is preferred
131;               when you do not wish to change the pixel values of the image.
132;               This keyword must be set, for example, when you are displaying
133;               GIF files that come with their own non-IDL color table vectors.
134;
135;     NORMAL:   Setting this keyword means image position coordinates x and y
136;               are interpreted as being in normalized coordinates. This keyword
137;               is only valid if the TV keyword is set.
138;
139;     OVERPLOT: Setting this keyword causes the POSITION keyword to be ignored
140;               and the image is positioned in the location established by the
141;               last graphics command. For example:
142;
143;                    Plot, Findgen(11), Position=[0.1, 0.3, 0.8, 0.95]
144;                    TVImage, image, /Overplot
145;
146;     POSITION: The location of the image in the output window. This is
147;               a four-element floating array of normalized coordinates of
148;               the type given by !P.POSITION or the POSITION keyword to
149;               other IDL graphics commands. The form is [x0, y0, x1, y1].
150;               The default is [0.0, 0.0, 1.0, 1.0]. Note that this keyword is ALSO
151;               an output keyword. That is to say, upon return from TVIMAGE
152;               this keyword (if passed by reference) contains the actual
153;               position in the window where the image was displayed. This
154;               may be different from the input values if the KEEP_ASPECT_RATIO
155;               keyword is set, or if you are using TVIMAGE with the POSITION
156;               keyword when !P.MULTI is set to something other than a single
157;               plot. One use for the output values might be to position other
158;               graphics (e.g., a colorbar) in relation to the image.
159;
160;               Note that the POSITION keyword should not, normally, be used
161;               when displaying multiple images with !P.MULTI. If it *is* used,
162;               its meaning differs slightly from its normal meaning. !P.MULTI
163;               is responsible for calculating the position of graphics in the
164;               display window. Normally, it would be a mistake to use a POSITION
165;               graphics keyword on a graphics command that was being drawn with
166;               !P.MULTI. But in this special case, TVIMAGE will use the POSITION
167;               coordinates to calculate an image position in the actual position
168;               calculated for the image by !P.MULTI. The main purpose of this
169;               functionality is to allow the user to display images along with
170;               colorbars when using !P.MULTI. See the example below.
171;
172;    QUIET:      There are situations when you would prefer that TVIMAGE does not
173;                advertise itself by filling out the FSC_$TVIMAGE common block. For
174;                example, if you are using TVIMAGE to draw a color bar, it would
175;                not be necessary. Setting this keyword means that TVIMAGE just
176;                goes quietly about it's business without bothering anyone else.
177;
178;    SCALE:     Set this keyword to byte scale the image before display.
179;
180;     TV:       Setting this keyword makes the TVIMAGE command work much
181;               like the TV command, although better. That is to say, it
182;               will still set the correct DECOMPOSED state depending upon
183;               the kind of image to be displayed (8-bit or 24-bit). It will
184;               also allow the image to be "positioned" in the window by
185;               specifying the coordinates of the lower-left corner of the
186;               image. The NORMAL keyword is activated when the TV keyword
187;               is set, which will indicate that the position coordinates
188;               are given in normalized coordinates rather than device
189;               coordinates.
190;
191;               Setting this keyword will ensure that the keywords
192;               KEEP_ASPECT_RATIO, MARGIN, MINUS_ONE, MULTI, and POSITION
193;               are ignored.
194;
195;      XRANGE:  If the AXES keyword is set, this keyword is a two-element vector
196;               giving the X axis range. By default, [0, size of image in X].
197;
198;      YRANGE:  If the AXES keyword is set, this keyword is a two-element vector
199;               giving the Y axis range. By default, [0, size of image in Y].
200;
201; OUTPUTS:
202;     None.
203;
204; SIDE EFFECTS:
205;     Unless the KEEP_ASPECT_RATIO keyword is set, the displayed image
206;     may not have the same aspect ratio as the input data set.
207;
208; RESTRICTIONS:
209;     If the POSITION keyword and the KEEP_ASPECT_RATIO keyword are
210;     used together, there is an excellent chance the POSITION
211;     parameters will change. If the POSITION is passed in as a
212;     variable, the new positions will be returned in the same variable
213;     as an output parameter.
214;
215;     If a 24-bit image is displayed on an 8-bit display, the
216;     24-bit image must be converted to an 8-bit image and the
217;     appropriate color table vectors. This is done with the COLOR_QUAN
218;     function. The TVIMAGE command will load the color table vectors
219;     and set the NOINTERPOLATION keyword if this is done. Note that the
220;     resulting color table vectors are normally incompatible with other
221;     IDL-supplied color tables. Hence, other graphics windows open at
222;     the time the image is display are likely to look strange.
223;
224;     Other programs from Coyote Library (e.g., FSC_COLOR) may also be
225;     required.
226;
227; EXAMPLE:
228;     To display an image with a contour plot on top of it, type:
229;
230;        filename = FILEPATH(SUBDIR=['examples','data'], 'worldelv.dat')
231;        image = BYTARR(360,360)
232;        OPENR, lun, filename, /GET_LUN
233;        READU, lun, image
234;        FREE_LUN, lun
235;
236;        TVIMAGE, image, POSITION=thisPosition, /KEEP_ASPECT_RATIO
237;        CONTOUR, image, POSITION=thisPosition, /NOERASE, XSTYLE=1, $
238;            YSTYLE=1, XRANGE=[0,360], YRANGE=[0,360], NLEVELS=10
239;
240;     To display four images in a window without spacing between them:
241;
242;     !P.Multi=[0,2,2]
243;     TVImage, image, Margin=0
244;     TVImage, image, Margin=0
245;     TVImage, image, Margin=0
246;     TVImage, image, Margin=0
247;     !P.Multi = 0
248;
249;     To display four image in a window with associated color bars:
250;
251;     !P.Multi=[0,2,2]
252;     p = [0.02, 0.3, 0.98, 0.98]
253;     LoadCT, 0
254;     TVImage, image, Position=p
255;     Colorbar, Position=[p[0], p[1]-0.1, p[2], p[1]-0.05]
256;     p = [0.02, 0.3, 0.98, 0.98]
257;     LoadCT, 2
258;     TVImage, image, Position=p
259;     Colorbar, Position=[p[0], p[1]-0.1, p[2], p[1]-0.05]
260;     p = [0.02, 0.3, 0.98, 0.98]
261;     LoadCT, 3
262;     TVImage, image, Position=p
263;     Colorbar, Position=[p[0], p[1]-0.1, p[2], p[1]-0.05]
264;     p = [0.02, 0.3, 0.98, 0.98]
265;     LoadCT, 5
266;     TVImage, image, Position=p
267;     Colorbar, Position=[p[0], p[1]-0.1, p[2], p[1]-0.05]
268;     !P.Multi =0
269;
270; MODIFICATION HISTORY:
271;      Written by:     David Fanning, 20 NOV 1996.
272;      Fixed a small bug with the resizing of the image. 17 Feb 1997. DWF.
273;      Removed BOTTOM and NCOLORS keywords. This reflects my growing belief
274;         that this program should act more like TV and less like a "color
275;         aware" application. I leave "color awareness" to the program
276;         using TVIMAGE. Added 24-bit image capability. 15 April 1997. DWF.
277;      Fixed a small bug that prevented this program from working in the
278;          Z-buffer. 17 April 1997. DWF.
279;      Fixed a subtle bug that caused me to think I was going crazy!
280;          Lession learned: Be sure you know the *current* graphics
281;          window! 17 April 1997. DWF.
282;      Added support for the PRINTER device. 25 June 1997. DWF.
283;      Extensive modifications. 27 Oct 1997. DWF
284;          1) Removed PRINTER support, which didn't work as expected.
285;          2) Modified Keep_Aspect_Ratio code to work with POSITION keyword.
286;          3) Added check for window-able devices (!D.Flags AND 256).
287;          4) Modified PostScript color handling.
288;      Craig Markwart points out that Congrid adds an extra row and column
289;          onto an array. When viewing small images (e.g., 20x20) this can be
290;          a problem. Added a Minus_One keyword whose value can be passed
291;          along to the Congrid keyword of the same name. 28 Oct 1997. DWF
292;      Changed default POSITION to fill entire window. 30 July 1998. DWF.
293;      Made sure color decomposition is OFF for 2D images. 6 Aug 1998. DWF.
294;      Added limited PRINTER portrait mode support. The correct aspect ratio
295;          of the image is always maintained when outputting to the
296;          PRINTER device and POSITION coordinates are ignored. 6 Aug 1998. DWF
297;      Removed 6 August 98 fixes (Device, Decomposed=0) after realizing that
298;          they interfere with operation in the Z-graphics buffer. 9 Oct 1998. DWF
299;      Added a MARGIN keyword. 18 Oct 1998. DWF.
300;      Re-established Device, Decomposed=0 keyword for devices that
301;         support it. 18 Oct 1998. DWF.
302;      Added support for the !P.Multi system variable. 3 March 99. DWF
303;      Added DEVICE, DECOMPOSED=1 command for all 24-bit images. 2 April 99. DWF.
304;      Added ability to preserve DECOMPOSED state for IDL 5.2 and higher. 4 April 99. DWF.
305;      Added TV keyword to allow TVIMAGE to work like the TV command. 11 May 99. DWF.
306;      Added the OVERPLOT keyword to allow plotting on POSITION coordinates
307;         estabished by the preceding graphics command. 11 Oct 99. DWF.
308;      Added automatic recognition of !P.Multi. Setting MULTI keyword is no
309;         longer required. 18 Nov 99. DWF.
310;      Added NOINTERPOLATION keyword so that nearest neighbor interpolation
311;         is performed rather than bilinear. 3 Dec 99. DWF
312;      Changed ON_ERROR condition from 1 to 2. 19 Dec 99. DWF.
313;      Added Craig Markwardt's CMCongrid program and removed RSI's. 24 Feb 2000. DWF.
314;      Added HALF_HALF keyword to support CMCONGRID. 24 Feb 2000. DWF.
315;      Fixed a small problem with image start position by adding ROUND function. 19 March 2000. DWF.
316;      Updated the PRINTER device code to take advantage of available keywords. 2 April 2000. DWF.
317;      Reorganized the code to handle 24-bit images on 8-bit displays better. 2 April 2000. DWF.
318;      Added BACKGROUND keyword. 20 April 2000. DWF.
319;      Fixed a small problem in where the ERASE was occuring. 6 May 2000. DWF.
320;      Rearranged the PLOT part of code to occur before decomposition state
321;         is changed to fix Background color bug in multiple plots. 23 Sept 2000. DWF.
322;      Removed MULTI keyword, which is no longer needed. 23 Sept 2000. DWF.
323;      Fixed a small problem with handling images that are slices from 3D image cubes. 5 Oct 2000. DWF.
324;      Added fix for brain-dead Macs from Ben Tupper that restores Macs ability to
325;         display images. 8 June 2001. DWF.
326;      Fixed small problem with multiple plots and map projections. 29 June 2003. DWF.
327;      Converted all array subscripts to square brackets. 29 June 2003. DWF.
328;      Removed obsolete STR_SEP and replaced with STRSPLIT. 27 Oct 2004. DWF.
329;      Small modification at suggestion of Karsten Rodenacker to increase size of
330;         images in !P.MULTI mode. 8 December 2004. DWF.
331;      Minor modifications on Karsten Rodenacker's own account concerning margination
332;         and TV behaviour. 8 December 2004. KaRo
333;      There was a small inconsistency in how the image was resized for PostScript as
334;         opposed to the display, which could occasionally result in a small black line
335;         to the right of the image. This is now handled consistently. 3 January 2007. DWF.
336;      Made a small change to CMCONGRID to permit nearest-neighbor interpolation for 3D arrays.
337;         Previously, any 24-bit image was interpolated, no matter the setting of the NOINTERP
338;         keyword. 22 April 2007. DWF.
339;      Updated the program for the 24-bit Z-buffer in IDL 6.4. 11 June 2007. DWF.
340;      Added new POSITION keyword functionality for !P.MULTI display. 9 Sept 2007. DWF.
341;      Bit one too many times. Added _STRICT_EXTRA keywords for all _EXTRA keywords. 1 Feb 2008. DWF.
342;      Added FSC_$TVIMAGE common block for interactive interaction with TVINFO. 16 March 2008. DWF.
343;      Added SCALE keyword. 18 March 2008. DWF.
344;      Added keywords to allow axes to be drawn around the image. 18 March 2008. DWF.
345;      Added QUIET keyword to allow by-passing of FSC_$TVIMAGE common block updating. 21 March 2008. DWF.
346;      Made BACKGROUND and ERASE valid keywords only on 24-bit devices. Ignored on others. 28 May 2008. DWF.
347;      Cannot make color work in device independent way for axes, unless I handle axis color directly. To this
348;          end, I have added an ACOLOR keyword. 16 June 2008. DWF.
349;      Added BREWER keyword so I can specify Brewer colors with BACKGROUND and ACOLOR keywords. 16 June 2008. DWF.
350;-
351;
352;###########################################################################
353;
354; LICENSE
355;
356; This software is OSI Certified Open Source Software.
357; OSI Certified is a certification mark of the Open Source Initiative.
358;
359; Copyright 2000-2008 Fanning Software Consulting.
360;
361; This software is provided "as-is", without any express or
362; implied warranty. In no event will the authors be held liable
363; for any damages arising from the use of this software.
364;
365; Permission is granted to anyone to use this software for any
366; purpose, including commercial applications, and to alter it and
367; redistribute it freely, subject to the following restrictions:
368;
369; 1. The origin of this software must not be misrepresented; you must
370;    not claim you wrote the original software. If you use this software
371;    in a product, an acknowledgment in the product documentation
372;    would be appreciated, but is not required.
373;
374; 2. Altered source versions must be plainly marked as such, and must
375;    not be misrepresented as being the original software.
376;
377; 3. This notice may not be removed or altered from any source distribution.
378;
379; For more information on Open Source Software, visit the Open Source
380; web site: http://www.opensource.org.
381;
382;###########################################################################
383;
384;
385; NAME:
386;  TVIMAGE_CONGRID
387;
388; PURPOSE:
389;       Shrink or expand the size of an array by an arbitrary amount.
390;       This IDL procedure simulates the action of the VAX/VMS
391;       CONGRID/CONGRIDI function.
392;
393;  This function is similar to "REBIN" in that it can resize a
394;       one, two, or three dimensional array.   "REBIN", however,
395;       requires that the new array size must be an integer multiple
396;       of the original size.   CONGRID will resize an array to any
397;       arbitrary size (REBIN is somewhat faster, however).
398;       REBIN averages multiple points when shrinking an array,
399;       while CONGRID just resamples the array.
400;
401; CATEGORY:
402;       Array Manipulation.
403;
404; CALLING SEQUENCE:
405;  array = TVIMAGE_CONGRID(array, x, y, z)
406;
407; INPUTS:
408;       array:  A 1, 2, or 3 dimensional array to resize.
409;               Data Type : Any type except string or structure.
410;
411;       x:      The new X dimension of the resized array.
412;               Data Type : Int or Long (greater than or equal to 2).
413;
414; OPTIONAL INPUTS:
415;       y:      The new Y dimension of the resized array.   If the original
416;               array has only 1 dimension then y is ignored.   If the
417;               original array has 2 or 3 dimensions then y MUST be present.
418;
419;       z:      The new Z dimension of the resized array.   If the original
420;               array has only 1 or 2 dimensions then z is ignored.   If the
421;               original array has 3 dimensions then z MUST be present.
422;
423; KEYWORD PARAMETERS:
424;       INTERP: If set, causes linear interpolation to be used.
425;               Otherwise, the nearest-neighbor method is used.
426;
427;       CUBIC:  If set, uses "Cubic convolution" interpolation.  A more
428;               accurate, but more time-consuming, form of interpolation.
429;               CUBIC has no effect when used with 3 dimensional arrays.
430;
431;       MINUS_ONE:
432;               If set, will prevent CONGRID from extrapolating one row or
433;               column beyond the bounds of the input array.   For example,
434;               If the input array has the dimensions (i, j) and the
435;               output array has the dimensions (x, y), then by
436;               default the array is resampled by a factor of (i/x)
437;               in the X direction and (j/y) in the Y direction.
438;               If MINUS_ONE is present (AND IS NON-ZERO) then the array
439;               will be resampled by the factors (i-1)/(x-1) and
440;               (j-1)/(y-1).
441;
442;       HALF_HALF:
443;               If set, will tell CONGRID to extrapolate a *half* row
444;               and column on either side, rather than the default of
445;               one full row/column at the ends of the array.  If you
446;               are interpolating images with few rows, then the
447;               output will be more consistent with this technique.
448;               This keyword is intended as a replacement for
449;               MINUS_ONE, and both keywords probably should not be
450;               used in the same call to CONGRID.
451;
452; OUTPUTS:
453;  The returned array has the same number of dimensions as the original
454;       array and is of the same data type.   The returned array will have
455;       the dimensions (x), (x, y), or (x, y, z) depending on how many
456;       dimensions the input array had.
457;
458; PROCEDURE:
459;       IF the input array has three dimensions, or if INTERP is set,
460;       then the IDL interpolate function is used to interpolate the
461;       data values.
462;       If the input array has two dimensions, and INTERP is NOT set,
463;       then the IDL POLY_2D function is used for nearest neighbor sampling.
464;       If the input array has one dimension, and INTERP is NOT set,
465;       then nearest neighbor sampling is used.
466;
467; EXAMPLE:
468;       ; vol is a 3-D array with the dimensions (80, 100, 57)
469;       ; Resize vol to be a (90, 90, 80) array
470;       vol = TVIMAGE_CONGRID(vol, 90, 90, 80)
471;
472; MODIFICATION HISTORY:
473;       DMS, Sept. 1988.
474;       DMS, Added the MINUS_ONE keyword, Sept. 1992.
475;  Daniel Carr. Re-wrote to handle one and three dimensional arrays
476;                    using INTERPOLATE function.
477;  DMS, RSI, Nov, 1993.  Added CUBIC keyword.
478;       Craig Markwardt, Dec, 1997.  Added halfhalf keyword to
479;                        more evenly distribute "dead" pixel row
480;       Use uniformly spaced grid points for half_half W. Landsman   Feb. 2000
481;              (and slightly modified by C. Markwardt 14 Feb 2000)
482;  DWF, FSC, 22 Apr 2007. Modified the program so that 3D arrays use nearest-neighbor
483;       interpolation unless the INTERP keyword is set.
484;  DWF, FSC, 22 Apr 2007. Function renamed from CMCONGRID to TVIMAGE_CONGRID on
485;       recommendation of Craig Markwardt as he wants no part of this. :-)
486
487
488FUNCTION TVIMAGE_CONGRID, arr, x, y, z, Interp=int, Minus_One=m1, Cubic = cubic, $
489                    Half_Half=hh
490
491    ON_ERROR, 2    ;Return to caller if error
492    s = Size(arr)
493   
494    IF ((s[0] EQ 0) OR (s[0] GT 3)) THEN $
495       Message, 'Array must have 1, 2, or 3 dimensions.'
496   
497    ;  Supply defaults = no interpolate, and no minus_one.
498    if n_elements(int) le 0 then int = 0 else int = keyword_set(int)
499    if n_elements(m1) le 0 then m1 = 0 else m1 = keyword_set(m1)
500   
501    ; Compute offsets pixel offsets for half_half
502    halfx = 0.0 & halfy = 0.0 & halfz = 0.0
503    if keyword_set(hh) then begin
504        if s[0] GE 1 then halfx = -0.5 + (float(s[1])/x)
505        if s[0] GE 2 then halfy = -0.5 + (float(s[2])/y)
506        if s[0] GE 3 then halfz = -0.5 + (float(s[3])/z)
507    endif
508    cub = KEYWORD_SET(cubic)
509    if cub THEN int = 1  ;Cubic implies interpolate
510   
511   
512    CASE s[0] OF
513       1: BEGIN          ; *** ONE DIMENSIONAL ARRAY
514       srx = float(s[1] - m1)/(x-m1) * findgen(x) + halfx
515          IF int THEN $
516             RETURN, INTERPOLATE(arr, srx, CUBIC = cub) ELSE $
517             RETURN, arr(ROUND(srx))
518       ENDCASE
519       2: BEGIN ; *** TWO DIMENSIONAL ARRAY
520       IF int THEN BEGIN
521         srx = float(s[1] - m1) / (x-m1) * findgen(x) + halfx
522         sry = float(s[2] - m1) / (y-m1) * findgen(y) + halfy
523              RETURN, INTERPOLATE(arr, srx, sry, /GRID, CUBIC=cub)
524       ENDIF ELSE $
525         RETURN, POLY_2D(arr, $
526          [[0,0],[(s[1]-m1)/float(x-m1),0]], $ ;Use poly_2d
527          [[0,(s[2]-m1)/float(y-m1)],[0,0]],int,x,y)
528   
529       ENDCASE
530       3: BEGIN ; *** THREE DIMENSIONAL ARRAY
531       srx = float(s[1] - m1) / (x-m1) * findgen(x) + halfx
532       sry = float(s[2] - m1) / (y-m1) * findgen(y) + halfy
533       srz = float(s[3] - m1) / (z-m1) * findgen(z) + halfz
534       IF int THEN BEGIN
535          RETURN, interpolate(arr, srx, sry, srz, /grid)
536       ENDIF ELSE BEGIN
537          RETURN, interpolate(arr, round(srx), round(sry), round(srz), /grid)
538       ENDELSE
539       ENDCASE
540    ENDCASE
541   
542    RETURN, arr_r
543END
544;--------------------------------------------------------------------------
545
546
547
548FUNCTION TVIMAGE_ERROR, theMessage, Traceback=traceback, NoName=noName, _Extra=extra
549
550    On_Error, 2
551   
552    ; Check for presence and type of message.
553    IF N_Elements(theMessage) EQ 0 THEN theMessage = !Error_State.Msg
554    s = Size(theMessage)
555    messageType = s[s[0]+1]
556    IF messageType NE 7 THEN BEGIN
557       Message, "The message parameter must be a string.", _Extra=extra
558    ENDIF
559   
560    ; Get the call stack and the calling routine's name.
561    Help, Calls=callStack
562    callingRoutine = (StrSplit(StrCompress(callStack[1])," ", /Extract))[0]
563   
564    ; Are widgets supported? Doesn't matter in IDL 5.3 and higher.
565    widgetsSupported = ((!D.Flags AND 65536L) NE 0) OR Float(!Version.Release) GE 5.3
566    IF widgetsSupported THEN BEGIN
567       IF Keyword_Set(noName) THEN answer = Dialog_Message(theMessage, _Extra=extra) ELSE BEGIN
568          IF StrUpCase(callingRoutine) EQ "$MAIN$" THEN answer = Dialog_Message(theMessage, _Extra=extra) ELSE $
569             answer = Dialog_Message(StrUpCase(callingRoutine) + ": " + theMessage, _Extra=extra)
570       ENDELSE
571    ENDIF ELSE BEGIN
572          Message, theMessage, /Continue, /NoPrint, /NoName, /NoPrefix, _Extra=extra
573          Print, '%' + callingRoutine + ': ' + theMessage
574          answer = 'OK'
575    ENDELSE
576   
577    ; Provide traceback information if requested.
578    IF Keyword_Set(traceback) THEN BEGIN
579       Help, /Last_Message, Output=traceback
580       Print,''
581       Print, 'Traceback Report from ' + StrUpCase(callingRoutine) + ':'
582       Print, ''
583       FOR j=0,N_Elements(traceback)-1 DO Print, "     " + traceback[j]
584       Print, ''
585    ENDIF
586   
587    RETURN, answer
588END
589
590
591
592PRO TVIMAGE, image, x, y, $
593   ACOLOR=acolor, $
594   AXIS=axis, $
595   AXES=axes, $
596   AXKEYWORDS=axkeywords, $
597   BACKGROUND=background, $
598   BREWER=brewer, $
599   ERASE=eraseit, $
600   HALF_HALF=half_half, $
601   KEEP_ASPECT_RATIO=keep, $
602   MARGIN=margin, $
603   MINUS_ONE=minusOne, $
604   NOINTERPOLATION=nointerp, $
605   NORMAL=normal, $
606   POSITION=position, $
607   OVERPLOT=overplot, $
608   QUIET=quiet, $
609   SCALE=scale, $
610   TV=tv, $
611   XRANGE=plotxrange, $
612   YRANGE=plotyrange, $
613   _EXTRA=extra
614
615    ; Error handling.
616    Catch, theError
617    IF theError NE 0 THEN BEGIN
618       Catch, /Cancel
619       ok = TVIMAGE_ERROR(Traceback=1, /Error)
620       IF Ptr_Valid(ptr) THEN BEGIN
621            image = Temporary(*ptr)
622            Ptr_Free, ptr
623       ENDIF
624       RETURN
625    ENDIF
626   
627    ; Set up a common block as input to TVINFO.
628    COMMON FSC_$TVIMAGE, _tvimage_xsize, _tvimage_ysize, $
629                         _tvimage_winxsize, _tvimage_winysize, $
630                         _tvimage_position, _tvimage_winID, $
631                         _tvimage_current
632   
633    ; Check for image parameter and keywords.
634    IF N_Elements(image) EQ 0 THEN MESSAGE, 'You must pass a valid image argument.', /NoName
635   
636    ; Did the user want me to scale the image.
637    IF Keyword_Set(scale) THEN BEGIN
638        ptr = Ptr_New(image, /NO_COPY)
639        image = BytScl(*ptr)
640    ENDIF
641    IF N_Elements(acolor) EQ 0 THEN acolor = !P.Color
642    IF Keyword_Set(axis) THEN axes = 1
643    axes = Keyword_Set(axes)
644    brewer = Keyword_Set(brewer)
645    interp = 1.0 - Keyword_Set(nointerp)
646    half_half = Keyword_Set(half_half)
647    minusOne = Keyword_Set(minusOne)
648    IF N_Elements(background) EQ 0 THEN background = !P.Background
649    IF Keyword_Set(eraseit) THEN BEGIN
650         IF (!D.Flags AND 256) NE 0 THEN BEGIN
651            Device, Get_Visual_Depth=theDepth
652            IF theDepth GE 24 THEN BEGIN
653               varType = Size(background, /TNAME)
654               CASE 1 OF
655                  varType EQ 'BYTE' OR varType EQ 'INT': BEGIN
656                     TVLCT, r, g, b, /GET
657                     Erase, Color=background
658                     TVLCT, r, g, b
659                     END
660                  varType EQ 'LONG': BEGIN
661                     Device, Decomposed=1, Get_Decomposed=theState
662                     Erase, Color=background
663                     Device, Decomposed=theState
664                     END
665                  varType EQ 'STRING': BEGIN
666                     Device, Decomposed=1, Get_Decomposed=theState
667                     Erase, Color=FSC_Color(background, BREWER=brewer)
668                     Device, Decomposed=theState
669                     END
670                  ELSE: BEGIN
671                     TVLCT, r, g, b, /GET
672                     Erase, Color=background
673                     TVLCT, r, g, b
674                     END
675               ENDCASE
676            ENDIF
677         ENDIF
678    ENDIF
679    IF (N_Elements(margin) GT 0) AND (Keyword_Set(margin) EQ 0) THEN vmargin=[0.,0.] ELSE vmargin=[1.,1.]
680   
681    ; Check image size.
682    s = Size(image)
683    IF s[0] LT 2 OR s[0] GT 3 THEN $
684       MESSAGE, 'Argument does not appear to be an image. Returning...', /NoName
685   
686    ; Allow 24-bit images and 2D images that are sent in as 3D
687    ; arrays where one dimension is a 1.
688    IF s[0] EQ 3 THEN BEGIN
689       IF (s[1] NE 3L) AND (s[2] NE 3L) AND (s[3] NE 3L) THEN BEGIN
690          IF (s[1] NE 1L) AND (s[2] NE 1L) AND (s[3] NE 1L) THEN BEGIN
691             MESSAGE, 'Argument does not appear to be a 24-bit image. Returning...', /NoName
692          ENDIF ELSE BEGIN
693             IF s[1] EQ 1 THEN single = 1
694             IF s[2] EQ 1 THEN single = 2
695             IF s[3] EQ 1 THEN single = 3
696             CASE single OF
697                1: image = Reform(image, s[2], s[3])
698                2: image = Reform(image, s[1], s[3])
699                3: image = Reform(image, s[1], s[2])
700             ENDCASE
701             s = Size(image)
702          ENDELSE
703       ENDIF
704    ENDIF ELSE s = Size(image)
705   
706    ; If a window is not open, open one, otherwise in X devices you get incorrect
707    ; window size information the first time you call TVIMAGE.
708    IF (!D.FLAGS AND 256) NE 0 THEN IF !D.Window EQ -1 THEN Window
709   
710    ; Which release of IDL is this?
711    thisRelease = Float(!Version.Release)
712   
713    ; Doing multiple plots?
714    IF Total(!P.Multi) GT 0 THEN multi = 1 ELSE multi = 0
715   
716    ; Check for position and overplot keywords.
717    IF N_Elements(position) EQ 0 THEN BEGIN
718       IF Keyword_Set(multi) AND (Keyword_Set(overplot) NE 1) THEN BEGIN
719          Plot, Findgen(11), XStyle=4, YStyle=4, /NoData, Background=background, XMargin=vmargin, YMargin=vmargin
720          position = [!X.Window[0], !Y.Window[0], !X.Window[1], !Y.Window[1]]
721       ENDIF ELSE BEGIN
722          IF Keyword_Set(overplot) THEN BEGIN
723             position = [!X.Window[0], !Y.Window[0], !X.Window[1], !Y.Window[1]]
724          ENDIF ELSE position = [0.0, 0.0, 1.0, 1.0]
725       ENDELSE
726    ENDIF ELSE BEGIN
727       IF Keyword_Set(multi) AND (Keyword_Set(overplot) NE 1)THEN BEGIN
728   
729          ; Draw the invisible plot to get plot position.
730          Plot, Findgen(11), XStyle=4, YStyle=4, /NoData, Background=background, XMargin=vmargin, YMargin=vmargin
731   
732          ; Use position coordinates to indicate position in this set of coordinates.
733          xrange = !X.Window[1] - !X.Window[0]
734          xstart = !X.Window[0] + position[0]*xrange
735          xend = xrange * (position[2] - position[0]) + xstart
736   
737          yrange = !Y.Window[1] - !Y.Window[0]
738          ystart = !Y.Window[0] + position[1]*yrange
739          yend = yrange * (position[3] - position[1]) + ystart
740   
741          ; New position based on !P.MULTI position.
742          position = [xstart, ystart, xend, yend]
743   
744       ENDIF ELSE BEGIN
745          IF Keyword_Set(overplot) THEN BEGIN
746             position = [!X.Window[0], !Y.Window[0], !X.Window[1], !Y.Window[1]]
747          ENDIF ELSE position = Float(position)
748       ENDELSE
749    ENDELSE
750   
751    ; Check for margin keyword.
752    IF (Keyword_Set(multi) EQ 0) AND (Keyword_Set(overplot) EQ 0) THEN BEGIN
753       IF N_Elements(margin) NE 0 THEN BEGIN
754               margin = 0.0 > margin < 0.33
755               position = [position[0] + margin, position[1] + margin, $
756                           position[2] - margin, position[3] - margin]
757       ENDIF
758    ENDIF
759   
760    ; 2D image.
761    IF s[0] EQ 2 THEN BEGIN
762   
763       imgXsize = FLOAT(s[1])
764       imgYsize = FLOAT(s[2])
765       true = 0
766   
767       ; Decomposed color off if device supports it.
768       CASE  StrUpCase(!D.NAME) OF
769            'X': BEGIN
770                Device, Get_Visual_Depth=thisDepth
771                IF thisRelease GE 5.2 THEN Device, Get_Decomposed=thisDecomposed
772                Device, Decomposed=0
773                ENDCASE
774            'WIN': BEGIN
775   
776                Device, Get_Visual_Depth=thisDepth
777                IF thisRelease GE 5.2 THEN Device, Get_Decomposed=thisDecomposed
778                Device, Decomposed=0
779                ENDCASE
780            'MAC': BEGIN
781                Device, Get_Visual_Depth=thisDepth
782                IF thisRelease GE 5.2 THEN Device, Get_Decomposed=thisDecomposed
783                Device, Decomposed=0
784                ENDCASE
785            'Z': BEGIN
786                ; Fix for 24-bit Z-buffer.
787                IF (Float(!Version.Release) GE 6.4) THEN BEGIN
788                   Device, Get_Decomposed=thisDecomposed, Get_Pixel_Depth=thisDepth
789                   Device, Decomposed=0
790                ENDIF ELSE thisDepth = 8
791                ENDCASE
792            ELSE: thisDepth = 8
793       ENDCASE
794   
795    ENDIF
796   
797    ; 3D image.
798    IF s[0] EQ 3 THEN BEGIN
799   
800       IF s[1] EQ 3 THEN true = 1 ; Pixel interleaved
801       IF s[2] EQ 3 THEN true = 2 ; Row interleaved
802       IF s[3] EQ 3 THEN true = 3 ; Band interleaved
803   
804       ; Decomposed color on if device supports it.
805       CASE StrUpCase(!D.NAME) OF
806          'X': BEGIN
807             Device, Get_Visual_Depth=thisDepth
808             IF thisRelease GE 5.2 THEN Device, Get_Decomposed=thisDecomposed
809             IF thisDepth GT 8 THEN Device, Decomposed=1
810             ENDCASE
811          'WIN': BEGIN
812             Device, Get_Visual_Depth=thisDepth
813             IF thisRelease GE 5.2 THEN Device, Get_Decomposed=thisDecomposed
814             IF thisDepth GT 8 THEN Device, Decomposed=1
815             ENDCASE
816          'MAC': BEGIN
817             Device, Get_Visual_Depth=thisDepth
818             IF thisRelease GE 5.2 THEN Device, Get_Decomposed=thisDecomposed
819             IF thisDepth GT 8 THEN Device, Decomposed=1
820             ENDCASE
821          'Z': BEGIN
822             ; Fix for 24-bit Z-buffer.
823             IF (Float(!Version.Release) GE 6.4) THEN BEGIN
824                Device, Get_Pixel_Depth=thisDepth
825                IF thisDepth GT 8 THEN Device, Decomposed=1
826             ENDIF
827             ENDCASE
828          ELSE: thisDepth = 8
829       ENDCASE
830   
831       CASE true OF
832          1: BEGIN
833             imgXsize = FLOAT(s[2])
834             imgYsize = FLOAT(s[3])
835             ENDCASE
836          2: BEGIN
837             imgXsize = FLOAT(s[1])
838             imgYsize = FLOAT(s[3])
839             ENDCASE
840          3: BEGIN
841             imgXsize = FLOAT(s[1])
842             imgYsize = FLOAT(s[2])
843             ENDCASE
844       ENDCASE
845   
846    ENDIF
847   
848    ; Check for TV keyword. If present, then act like a TV command.
849    IF Keyword_Set(tv) THEN BEGIN
850   
851       IF N_Params() GE 3 OR N_Params() EQ 1 THEN BEGIN
852         IF N_Elements(x) EQ 0 THEN x = 0
853         IF N_Elements(y) EQ 0 THEN y = 0
854         IF Keyword_Set(normal) THEN TV, image, x, y, True=true, _STRICT_EXTRA=extra, /Normal ELSE $
855                                     TV, image, x, y, True=true, _STRICT_EXTRA=extra, /Device
856       ENDIF ELSE BEGIN
857         IF N_Params() EQ 2 THEN BEGIN
858             IF Keyword_Set(normal) THEN TV, image, x, True=true, _STRICT_EXTRA=extra, /Normal ELSE $
859                                         TV, image, x, True=true, _STRICT_EXTRA=extra, /Device
860         ENDIF
861       ENDELSE
862       GoTo, restoreDecomposed
863   
864    ENDIF
865   
866    ; Maintain aspect ratio (ratio of height to width)?
867    IF KEYWORD_SET(keep) THEN BEGIN
868   
869       ; Find aspect ratio of image.
870       ratio = FLOAT(imgYsize) / imgXSize
871   
872       ; Find the proposed size of the image in pixels without aspect
873       ; considerations.
874       xpixSize = (position(2) - position(0)) * !D.X_VSize
875       ypixSize = (position(3) - position(1)) * !D.Y_VSize
876   
877       ; Try to fit the image width. If you can't maintain
878       ; the aspect ratio, fit the image height.
879       trialX = xpixSize
880       trialY = trialX * ratio
881       IF trialY GT ypixSize THEN BEGIN
882          trialY = ypixSize
883          trialX = trialY / ratio
884       ENDIF
885   
886       ; Recalculate the position of the image in the window.
887       position[0] = (((xpixSize - trialX) / 2.0) / !D.X_VSize) + position[0]
888       position[2] = position[0] + (trialX/FLOAT(!D.X_VSize))
889       position[1] = (((ypixSize - trialY) / 2.0) / !D.Y_VSize)  + position[1]
890       position[3] = position[1] + (trialY/FLOAT(!D.Y_VSize))
891   
892    ENDIF
893   
894    ; Calculate the image size and start locations.
895    xsize = Ceil((position[2] - position[0]) * !D.X_VSIZE)
896    ysize = Ceil((position[3] - position[1]) * !D.Y_VSIZE)
897    xstart = Round(position[0] * !D.X_VSIZE)
898    ystart = Round(position[1] * !D.Y_VSIZE)
899   
900    ; Display the image. Sizing different for scalable pixels devices.
901    IF (!D.Flags AND 1) NE 0 THEN BEGIN
902   
903       ; Need a gray-scale color table if this is a true
904       ; color image.
905       IF true GT 0 THEN LOADCT, 0, /Silent
906       TV, image, xstart, ystart, XSIZE=xsize, $
907          YSIZE=ysize, _STRICT_EXTRA=extra, True=true
908   
909    ENDIF ELSE BEGIN ; All other devices.
910   
911       CASE true OF
912          0: TV, TVIMAGE_CONGRID(image, xsize, ysize, INTERP=interp, $
913                MINUS_ONE=minusOne, HALF_HALF=half_half), xstart, $
914                ystart, _STRICT_EXTRA=extra
915          1: IF thisDepth GT 8 THEN BEGIN
916                TV, TVIMAGE_CONGRID(image, 3, xsize, ysize, INTERP=interp, $
917                   MINUS_ONE=minusOne, HALF_HALF=half_half), xstart, $
918                   ystart, _STRICT_EXTRA=extra, True=1
919             ENDIF ELSE BEGIN
920                image2d = Color_Quan(image, 1, r, g, b)
921                TVLCT, r, g, b
922                TV, TVIMAGE_CONGRID(image2d, xsize, ysize, INTERP=0, $
923                   MINUS_ONE=minusOne, HALF_HALF=half_half), xstart, $
924                   ystart, _STRICT_EXTRA=extra, True=0
925             ENDELSE
926          2: IF thisDepth GT 8 THEN BEGIN
927                TV, TVIMAGE_CONGRID(image, xsize, 3, ysize, INTERP=interp, $
928                   MINUS_ONE=minusOne, HALF_HALF=half_half), xstart, $
929                   ystart, _STRICT_EXTRA=extra, True=2
930             ENDIF ELSE BEGIN
931                image2d = Color_Quan(image, 2, r, g, b, _STRICT_EXTRA=extra)
932                TVLCT, r, g, b
933                TV, TVIMAGE_CONGRID(image2d, xsize, ysize, INTERP=0, $
934                   MINUS_ONE=minusOne, HALF_HALF=half_half), xstart, $
935                   ystart, _STRICT_EXTRA=extra, True=0
936             ENDELSE
937          3: IF thisDepth GT 8 THEN BEGIN
938                TV, TVIMAGE_CONGRID(image, xsize, ysize, 3, INTERP=interp, $
939                   MINUS_ONE=minusOne, HALF_HALF=half_half), xstart, $
940                   ystart, _STRICT_EXTRA=extra, True=3
941             ENDIF ELSE BEGIN
942                image2d = Color_Quan(image, 3, r, g, b, _STRICT_EXTRA=extra)
943                TVLCT, r, g, b
944                TV, TVIMAGE_CONGRID(image2d, xsize, ysize, INTERP=0, $
945                   MINUS_ONE=minusOne, HALF_HALF=half_half), xstart, $
946                   ystart, _STRICT_EXTRA=extra, True=0
947             ENDELSE
948      ENDCASE
949    ENDELSE
950       
951    ; Restore Decomposed state if necessary.
952    RestoreDecomposed:
953   
954    CASE StrUpCase(!D.NAME) OF
955       'X': BEGIN
956          IF thisRelease GE 5.2 THEN Device, Decomposed=thisDecomposed
957          ENDCASE
958       'WIN': BEGIN
959          IF thisRelease GE 5.2 THEN Device, Decomposed=thisDecomposed
960          ENDCASE
961       'MAC': BEGIN
962          IF thisRelease GE 5.2 THEN BEGIN
963             Device, Decomposed=thisDecomposed
964   
965             ; Here is a hack that fixes a longstanding Mac problem with
966             ; color tables after changing the decomposed state.
967             TV, [0]
968          ENDIF
969          ENDCASE
970       'Z': BEGIN
971          IF thisRelease GE 6.4 THEN Device, Decomposed=thisDecomposed
972          ENDCASE
973       ELSE:
974    ENDCASE
975
976    ; Set up common block parameters, but only if device supports windows.
977    ; And only if the QUIET flag is not turned on.
978    IF ~Keyword_Set(quiet) THEN BEGIN
979        IF (!D.FLAGS AND 256) NE 0 THEN BEGIN
980            _tvimage_xsize = imgXsize
981            _tvimage_ysize = imgYsize
982            _tvimage_winID = !D.Window
983            _tvimage_winxsize = !D.X_Size
984            _tvimage_winysize = !D.Y_Size
985            _tvimage_position = position
986            _tvimage_current = 1
987        ENDIF
988    ENDIF
989   
990    ; If the user wanted axes, draw them now.
991    IF axes THEN BEGIN
992   
993         ; Save plot system variables and current color table.
994        bangp = !P
995        bangx = !X
996        bangy = !Y
997        TVLCT, r, g, b, /GET
998   
999        ; If axes color is string, convert it.
1000        IF Size(acolor, /TNAME) EQ 'STRING' THEN acolor = FSC_COLOR(acolor, BREWER=brewer)   
1001   
1002        ; Need a data range?
1003        IF N_Elements(plotxrange) EQ 0 THEN plotxrange = [0, imgXsize]
1004        IF N_Elements(plotyrange) EQ 0 THEN plotyrange = [0, imgYsize]
1005        PLOT, [0], /NODATA, /NOERASE, XRANGE=plotxrange, YRANGE=plotyrange, $
1006            XSTYLE=1, YSTYLE=1, POSITION=position, COLOR=acolor, _STRICT_EXTRA=axkeywords
1007           
1008        ; Clean up after yourself.
1009        TVLCT, r, g, b
1010        !P = bangp
1011        !X = bangx
1012        !Y = bangy
1013    ENDIF
1014
1015    ; If you scaled the data, but the image back.
1016    IF Ptr_Valid(ptr) THEN BEGIN
1017        image = Temporary(*ptr)
1018        Ptr_Free, ptr
1019    ENDIF
1020END
Note: See TracBrowser for help on using the repository browser.