Viewing contents of file '../idllib/contrib/buie/digit.pro'
;+
; NAME:
;    digit
; PURPOSE: (one line)
;    Digitize from a displayed gif file.
; DESCRIPTION:
; CATEGORY:
;    Image display
; CALLING SEQUENCE:
;    digit, image, outfile
; INPUTS:
;    image   : Image to be displayed.  May be a string scalar containing the
;              name of a GIF file to be loaded and displayed, or an image
;              array to be displayed.
;    outfile : File into which collected points are saved.
; OPTIONAL INPUT PARAMETERS:
; KEYWORD INPUT PARAMETERS:
;    NATURAL    = If set, the natural screen coordinates are used.  No
;                 control points are solicited and no coordinate
;                 transformations are computed.
;    NOSCALE    = If set, the image is displayed without being scaled.
;    ROTATE     = Rotation angle (in degrees) for the gif image.  Allowed
;                 values are 90, 180, and 270 counterclockwise.
; OUTPUTS:
; KEYWORD OUTPUT PARAMETERS:
;    XVEC, YVEC = If both of these keywords are present, the collected
;                 coordinates are returned as vectors to the variables
;                 specified in the keywords.  The collected coordinates are
;                 always written to the output file.
; COMMON BLOCKS:
; SIDE EFFECTS:
; RESTRICTIONS:
; PROCEDURE:
;    Unless the 'NATURAL' keyword is specified, four control points and four
; associated values are requested in order to define the x and y axes and
; scale factors.
;    The first two points are the x-axis control points (and their values) and
; the second two are the y-axis control points (and their values).
;    Control vectors are computed from the requested control points and
; coordinate transformations are computed using simple vector algebra.
; MODIFICATION HISTORY:
;  Written by Doug Loucks, Lowell Observatory, April, 1993.
;  94/10/04 - MWB - moved cr to front of print statement (v3.6 bug workaround)
;-
PRO digit, image, outfile, NATURAL=natural, NOSCALE=noscale, ROTATE=in_angle, $
    XVEC=xvec, YVEC=yvec

; Check for required parameters.
IF N_PARAMS() NE 2 THEN BEGIN
   MESSAGE, 'digit, image, outfile', /INFO
   RETURN
ENDIF

image_size = SIZE( image )
IF image_size[0] EQ 0 AND image_size[1] EQ 7 THEN BEGIN
   ; Parameter is a scalar string.  If the file exists, load it into a local
   ; variable.
   IF NOT exists( image ) THEN BEGIN
      MESSAGE, 'File ' + image + ' does not exist.', /INFO
      RETURN
   ENDIF
   read_gif, image, l_image
   type = 7
ENDIF ELSE BEGIN
   ; Parameter should be an array of rank 2.
   IF badpar( image, [1,2,3,4,5], 2, CALLER='% DIGIT: (image) ', $
   TYPE=type ) THEN RETURN
ENDELSE

; Check the output file name.
IF outfile EQ '' OR outfile EQ ' ' THEN BEGIN
   MESSAGE, 'outfile parameter must be non-blank.', /INFO
   RETURN
ENDIF

; Define a few ASCII control characters.
bel = STRING( 7B )
cr  = STRING( 13B )
lf  = STRING( 10B )

; Initialize the coordinate vectors.
xvec = [ 0.0 ]
yvec = [ 0.0 ]

IF type EQ 7 THEN BEGIN
   ; The image parameter is a scalar string containing a GIF filename.
   image_size = SIZE( l_image )
ENDIF ELSE BEGIN
   image_size = SIZE( image )
ENDELSE

wsize = FLOAT( [ !d.x_size, !d.y_size ] )

IF KEYWORD_SET( in_angle ) THEN angle=in_angle ELSE angle=0
CASE angle OF
    90  : BEGIN
      isize = [ image_size[2], image_size[1] ]
      direction = 1
   END
   180  : BEGIN
      isize = [ image_size[1:2] ]
      direction = 2
   END
   270  : BEGIN
      isize = [ image_size[2], image_size[1] ]
      direction = 3
   END
   ELSE : BEGIN
      isize = [ image_size[1:2] ]
      direction = 0
   END
ENDCASE

sf = MIN( wsize / FLOAT(isize) )
;PRINT, 'Scale factor: ', sf

; Display the image.
nscale = KEYWORD_SET( noscale )
CASE nscale OF
   0 : BEGIN
      ; Display the image, scaled to fit into the IDL draw window.
      IF type EQ 7 THEN BEGIN
         ; Image parameter is a string scalar containing a GIF filename.  The
         ; file was loaded into a local image array.
         TVSCL,CONGRID( ROTATE(l_image,direction), isize[0]*sf, isize[1]*sf, $
         /INTERP )
      ENDIF ELSE BEGIN
         ; Image parameter is an image array.
         TVSCL,CONGRID( ROTATE(image,direction), isize[0]*sf, isize[1]*sf, $
         /INTERP )
      ENDELSE
   END
   1 : BEGIN
      ; Display the image without scaling.
      IF type EQ 7 THEN BEGIN
         ; Image parameter is a string scalar containing a GIF filename.  The
         ; file was loaded into a local image array.
         TVSCL, ROTATE( l_image, direction )
      ENDIF ELSE BEGIN
         ; Image parameter is an image array.
         TVSCL, ROTATE( image, direction )
      ENDELSE
   END
ENDCASE


IF NOT KEYWORD_SET( natural ) THEN BEGIN
   ; Coordinate transformations will be computed.
   ; Ask for the x-axis control points and their associated values.
   !mouse.button = 0
   WHILE !mouse.button NE 1 DO BEGIN
      PRINT, 'First x-axis control point (left=accept, right=exit).' + bel
      CURSOR, xa1, ya1, WAIT=3, /DEVICE
      IF !mouse.button EQ 4 THEN RETURN
   ENDWHILE
   READ, '... x-value for this point>' + bel, x1
   PRINT, ''

   !mouse.button = 0
   WHILE !mouse.button NE 1 DO BEGIN
      PRINT, 'Second x-axis control point (left=accept, right=exit).' + bel
      CURSOR, xa2, ya2, WAIT=3, /DEVICE
      IF !mouse.button EQ 4 THEN RETURN
   ENDWHILE
   READ, '... x-value for this point>' + bel, x2
   PRINT, ''

   ; Compute the x-axis control vectors and magnitudes.
   va1 = [ xa2-xa1, ya1-ya1 ]
   vb1 = [ xa2-xa2, ya2-ya1 ]
   vc1 = va1 + vb1
   ;
   magva1 = SQRT( TOTAL( va1*va1 ) )
   magvb1 = SQRT( TOTAL( vb1*vb1 ) )
   magvc1 = SQRT( TOTAL( vc1*vc1 ) )

   ; Compute the x-axis scale factor.
   sx = ( x2-x1 ) / magvc1

   ; Ask for the y-axis control points and their associated values.
   !mouse.button = 0
   WHILE !mouse.button NE 1 DO BEGIN
      PRINT, 'First y-axis control point (left=accept, right=exit).' + bel
      CURSOR, xb1, yb1, WAIT=3, /DEVICE
      IF !mouse.button EQ 4 THEN RETURN
   ENDWHILE
   READ, '... y-value for this point>' + bel, y1
   PRINT, ''

   !mouse.button = 0
   WHILE !mouse.button NE 1 DO BEGIN
      PRINT, 'Second y-axis control point (left=accept, right=exit).' + bel
      CURSOR, xb2, yb2, WAIT=3, /DEVICE
      IF !mouse.button EQ 4 THEN RETURN
   ENDWHILE
   READ, '... y-value for this point>' + bel, y2
   PRINT, ''

   ; Compute the y-axis control vectors and magnitudes.
   va2 = [ xb2-xb1, yb2-yb2 ]
   vb2 = [ xb1-xb1, yb2-yb1 ]
   vc2 = va2 + vb2

   magva2 = SQRT( TOTAL( va2*va2 ) )
   magvb2 = SQRT( TOTAL( vb2*vb2 ) )
   magvc2 = SQRT( TOTAL( vc2*vc2 ) )

   ; Compute the y-axis scale factor.
   sy = ( y2-y1 ) / magvc2
ENDIF

PRINT, 'Left mouse button enters points, middle button enters a blank line.'
PRINT, '... right mouse button to exit.'

ON_ERROR, 2
fmt = "($,a,'x=',G20.4,4X,'y=',G20.4)"

; Begin the main loop for tracking the mouse cursor and collecting the points.
npts = 0
!mouse.button = 0
WHILE !mouse.button NE 4 DO BEGIN
   ; Track the cursor position in device coordinates.
   CURSOR, xm, ym, 2, /DEVICE
   IF KEYWORD_SET( natural ) THEN BEGIN
      ; Use actual device coordinates.
      x = xm
      y = ym
   ENDIF ELSE BEGIN
      ; Compute the coordinates from the coordinate transformation vectors.
      va = [ xm-xa1, ya1-ya1 ]
      magva = SQRT( TOTAL( va*va ) )
      magvb = magva * ( magvb1 / magva1 )
      vb = [ xm-xm, magvb ]
      v = va + vb
      magv = SQRT( TOTAL( v*v ) )
      IF xm-xa1 LT 0 THEN x=x1-(sx*magv) ELSE x=x1+(sx*magv)

      vb = [ xb1-xb1, ym-yb1 ]
      magvb = SQRT( TOTAL( vb*vb ) )
      magva = magvb * ( magva2 / magvb2 )
      va = [ magva, ym-ym ]
      v = vb + va
      magv = SQRT( TOTAL( v*v ) )
      IF ym-yb1 LT 0 THEN y=y1-(sy*magv) ELSE y=y1+(sy*magv)
   ENDELSE

   IF !mouse.button eq 1 or !mouse.button eq 2 THEN BEGIN
      ; Left (or middle) mouse button pressed.
      IF !mouse.button EQ 1 THEN BEGIN
         ; Left mouse button pressed.
         ; Save the position into the output file and move to a new print line.
         PRINT, lf, x, y, FORMAT=fmt
         GET_LUN, lu
         OPENW, lu, outfile, /APPEND
         PRINTF, lu, x, y, FORMAT='(G20.4,4X,G20.4)'
         FREE_LUN, lu
         xvec = [ xvec, x ]
         yvec = [ yvec, y ]
         npts = npts + 1
      ENDIF ELSE BEGIN
         ; Middle mouse button pressed.  Move to a new print line and put a
         ; blank line into the output file.
         PRINT, '                                                  '
         OPENW, lu, outfile, /APPEND
         PRINTF, lu
         FREE_LUN, lu
      ENDELSE
      WHILE ( !mouse.button NE 0 ) DO BEGIN
         CURSOR, xx, yy, 4, /DEVICE
      ENDWHILE
   ENDIF
   PRINT, cr, x, y, FORMAT=fmt
ENDWHILE

PRINT, FORMAT='(/)'

PRINT, 'Selected points saved to file ' + outfile + '.'
IF KEYWORD_SET( xvec ) AND KEYWORD_SET( yvec ) AND npts GT 0 THEN BEGIN
   xvec = xvec[ 1 : npts ]
   yvec = yvec[ 1 : npts ]
ENDIF
END