; Copyright (c) 1995, Research Systems, Inc. All rights reserved. ; Unauthorized reproduction prohibited. ;+ ; NAME: Animate ; ; PURPOSE: This example demonstrates animation. ; ; MAJOR TOPICS: Animation and Widgets. ; ; CALLING SEQUENCE: Animate ; ; PROCEDURE: Animate uses the compound widget CW_ANIMATE ... ; ; MAJOR FUNCTIONS and PROCEDURES: ; CW_ANIMATE: ; CW_ANIMATE_INIT: ; CW_ANIMATE_LOAD: ; CW_ANIMATE_RUN: ; ; MODIFICATION HISTORY: Written by: WSO, RSI, January 1995 ; Modified by: ... ;- ; ; ColorSystem is a procedure to determine if the current device ; is in true color mode and whether or not colors are decomposed. ; ; If the the number of available colors is greater than 256 then ; you are in true color mode and colors are decomposed. Decomposed ; meaning that colors are indexed from three separate 256 entry ; color tables (red, green, blue). Decomposed will be false when one ; 256 entry color table is used to map to the three separate ; 256 entry color tables (red, green, blue). This will emulate ; indexed color. PRO ColorSystem, TRUE_COLOR=true_color, DECOMPOSED_COLOR=decomposed_color ; Create an off screen window to force the system to its default ; color system. This is really only required on X. WINDOW, /FREE, /PIXMAP pixmap = !D.WINDOW ; Remove it. Only needed it to initialize window color system. WDELETE, pixmap ; If the the number of available colors is greater than 256 then ; you are in true color mode and colors are decomposed. IF !D.N_COLORS GT 256 THEN BEGIN true_color = 1 decomposed_color = 1 ENDIF ELSE BEGIN ; Need to catch an error if the system doesn't allow you to set the ; DECOMPOSED keyword. This could happen if you are not in true color ; mode. Therefore, you must be in non true color (indexed color) mode. CATCH, errorStatus ; Initially errorStatus is zero (no error). It becomes non-zero when ; an error occurs further in this procedure. At that point, IDL execution ; will jump to here and start execution again. ; If errorStatus is not equal to zero - we must be in indexed color mode. IF errorStatus NE 0 THEN BEGIN true_color = 0 decomposed_color = 0 ENDIF ELSE BEGIN ; Try turning on DECOMPOSED color DEVICE, DECOMPOSED=1 ; If after turning on DECOMPOSED color, the number of available ; colors is now greater than 256 - we must be in true color mode. IF !D.N_COLORS GT 256 THEN BEGIN true_color = 1 decomposed_color = 0 ENDIF ELSE BEGIN ; If after turning on DECOMPOSED color, the number of available ; colors is not greater than 256 - we must be in indexed color mode. true_color = 0 decomposed_color = 0 ENDELSE ; Reset back to non-decomposed color DEVICE, DECOMPOSED=0 ENDELSE ENDELSE END ; This function is called whenever the user wants to load a new set ; of images into the cw_animate compound widget (animation viewer). ; FUNCTION OpenImage, animateWindow, animateBase, DESCRIPTION=description ; Prompt the user for a animation file to open and ; return a pointer to the file data GetImage, frames, DESCRIPTION=description, $ DIMENSIONS=dimensions, SUBDIR = ["examples","data"], $ /THREE_DIM, TITLE="Select Animation", /ASSOC_IT ; Was the GetImage successful (frame image is 2 dimensions) fileOK = (SIZE(frames))(0) GT 1 ; If GetImage was successful IF fileOK THEN BEGIN ; Get the size of the screen DEVICE, GET_SCREEN=screenSize ; Try for approx 1/2 the vertical height of the screen zoomFactor = (screenSize(1)/2.0) / dimensions(1) ;Vertical zoom ; First we need to determine if we are in true color mode ; in order to calculate how much memory is required. ColorSystem, TRUE_COLOR=true_color, DECOMPOSED_COLOR=decomposed_color ; If in true color mode, images take up more memory to hold the color ; information IF true_color THEN $ ; 3 (24 bit) or 4 bytes depending on the system (4 worst case) color_byte_depth = 4 $ ELSE $ ; Indexed color mode, so images only require 1 byte per pixel color_byte_depth = 1 ; Memory required is the frame dimensions times the number of frames ; times the bytes per pixel. memoryRequired = dimensions(0) * dimensions(1) * dimensions(2) * $ color_byte_depth ; Try for about 6 MB of animation memory, ; in order to fit in memory on small systems. zoomFactorMem = SQRT(6.0e6 / memoryRequired) ; Whichever is smaller, yet at least 1. zoomFactor = FLOOR(zoomFactor < zoomFactorMem > 1.0) ; If the window for the animation doesn't yet exist - create it. ; In other words, if this procedure is called from below in the ; Animate procedure. IF N_ELEMENTS(animateBase) EQ 0 THEN BEGIN ; In order to keep the desired layout, if the horizontal image ; dimension is greater than the vertical image dimension, flip ; the image dimensions so that horizontal is vertical and visaversa. IF dimensions(0) GT dimensions(1) THEN $ animateBase = CW_ANIMATE(animateWindow, dimensions(1)*zoomFactor, $ dimensions(0)*zoomFactor, dimensions(2), $ /NO_KILL, OPEN_FUNC="OpenImage") $ ELSE $ animateBase = CW_ANIMATE(animateWindow, dimensions(0)*zoomFactor, $ dimensions(1)*zoomFactor, dimensions(2), $ /NO_KILL, OPEN_FUNC="OpenImage") ; Set the window title and show the window WIDGET_CONTROL, animateWindow, TLB_SET_TITLE=description, $ /REALIZE;, /HOURGLASS ENDIF ELSE BEGIN ; The window exists and is already shown, so just set the title to the new ; animation file description. This case occurs when a user has ; selected the Open... button on the animation compound widget. WIDGET_CONTROL, animateWindow, TLB_SET_TITLE=description;, /HOURGLASS ; In order to keep the desired layout, if the horizontal image ; dimension is greater than the vertical image dimension, flip ; the image dimensions so that horizontal is vertical and visaversa. IF dimensions(0) GT dimensions(1) THEN $ ; Reinitialize the animation compound widget and set the dimensions ; of the new animation image data. CW_ANIMATE_INIT, animateBase, dimensions(1) * zoomFactor, $ dimensions(0) * zoomFactor, dimensions(2) $ ELSE $ CW_ANIMATE_INIT, animateBase, dimensions(0) * zoomFactor, $ dimensions(1) * zoomFactor, dimensions(2) ENDELSE ; Allocate a temporary chunk of memory. This is done to allow for the ; case when loading animations takes up all available memory. At that ; point an error will be flagged and caught by the CATCH statement ; below with a nonzero error status. This will then fall through ; to the else clause and free up (assigned to a smaller allocation - ; integer) memory to allow the animation to continue with just the ; frames that had space to load. temporaryBuffer = BYTARR(250000) CATCH, errorStatus IF errorStatus EQ 0 THEN BEGIN ; For each frame of the animation FOR index = 0, dimensions(2)-1 DO BEGIN ; Make sure the animation window hasn't been closed validID = WIDGET_INFO(animateBase, /VALID_ID) ; If the window was closed during loading - IF validID EQ 0 THEN $ MESSAGE, "", /NOPRINT ; Force the CATCH to break out of the loop ; If some sort of image resizing is required (in order to fit the ; screen sizing and memory restrictions) - IF zoomFactor GT 1 THEN $ ; Enlarge each frame of the animation newFrame = REBIN(frames(index), dimensions(0) * zoomFactor, $ dimensions(1) * zoomFactor) $ ELSE $ newFrame = frames(index) ; If the horizontal length is greater than the vertical height ; Flip it 90 degrees IF dimensions(0) GT dimensions(1) THEN $ newFrame = TRANSPOSE(newFrame) ; Load the frame into the animation CW_ANIMATE_LOAD, animateBase, IMAGE=newFrame, FRAME=index ENDFOR ENDIF ELSE BEGIN temporaryBuffer = 0 ENDELSE ; Retrieve the info for the ASSOCiated file to get the logical unit assoc_image = FSTAT(frames) ; Using the just retrieved lun - close and free it. FREE_LUN, assoc_image.unit ENDIF RETURN, fileOK END PRO CleanUpAnimate, wAnimateWindow ; Get the color table saved in the window's user value WIDGET_CONTROL, wAnimateWindow, GET_UVALUE=colorTable ; Restore the previous color table. TVLCT, colorTable END PRO Animate, GROUP = group ; Get the current color vectors to restore when this application is exited. TVLCT, savedR, savedG, savedB, /GET ; Build color table from color vectors colorTable = [[savedR],[savedG],[savedB]] ; Create a non-sizable window at location 30,30 wAnimateWindow = WIDGET_BASE(YOFFSET=30, XOFFSET=30, TLB_FRAME_ATTR=1, $ UVALUE=colorTable) ; Load a default color table for the animations LOADCT, 3, /SILENT ; Prompt the user for a animation file and then load it IF OpenImage(wAnimateWindow, animateBase) THEN BEGIN ; Set default cursor to arrow cursor DEVICE, /CURSOR_ORIGINAL ; If the animation loaded OK - run the animation CW_ANIMATE_RUN, animateBase ; Tell Xmanager to start the animation widget application XMANAGER, 'AnimateDemo', wAnimateWindow, GROUP_LEADER=group, $ CLEANUP="CleanUpAnimate" ENDIF ELSE $ ; The user canceled the animation selection window - so clean up CleanUpAnimate, wAnimateWindow END