| IntroductionOver the years, many people have felt the need to create their own
    image processing programs. They have ranged from the few hardy types who
    invented the data formats we know and love (NDF, FITS, IRAF, Figaro,
    etc.), to the more modest majority who have to wrestle with these formats
    and the various ways of accessing them.  Some people, perhaps, still have
    private image formats of their own. "Wouldn't it be nice...", we've been told, "... if there were just one
    way of accessing an image -- no matter where it came from?". Well now there is. It takes the form of a subroutine library, called
    IMG, designed for easy use by the majority of astronomers. IMG offers
    enormous flexibility by giving straightforward, no-nonsense access to most
    of the mainstream astronomical data formats. As a bonus, it can also be
    used from both the Fortran and C programming languages. Simple Image AccessFor example, accessing an input image "in" uses just one call: 
    
CALL IMG_IN( 'IN', NX, NY, IP, STATUS )  (Fortran)
imgIn( "in", nx, ny, ip, status );       (C)
     and getting a new image "out" (initialised with a copy
    of "in") is one more call: 
    
CALL IMG_OUT( 'IN', 'OUT', IP, STATUS )
imgOut( "in", "out", ip, status );
     You are not restricted to 2-dimensional "images" either. Spectra and
    data cubes can be accessed in the same way just by adding the number of
    dimensions to the routine name (two dimensions being the default): 
    
CALL IMG_IN1( 'SPECTRUM', NPIX, IP, STATUS )
CALL IMG_IN3( 'CUBE', NX, NY, NZ, IP, STATUS )
imgIn1( "spectrum", npix, ip, status );
imgIn3( "cube", nx, ny, nz, ip, status );
     You can also use whatever data type you choose simply by adding a
    further character to the routine name: 
    
CALL IMG_IN1D( 'SPECTRUM', NPIX, IP, STATUS )
CALL IMG_INI( 'IN', NX, NY, IP, STATUS )
CALL IMG_IN3W( 'CUBE', NX, NY, NZ, IP, STATUS )
imgIn1d( "spectrum", npix, ip, status );
imgIni( "in", nx, ny, ip, status );
imgIn3s( "cube", nx, ny, nz, ip, status );
     In this example, we access a DOUBLE PRECISION (double in C) spectrum,
    an INTEGER (int) image and an INTEGER*2 (short) cube. The default is REAL
    (float in C). A Fortran ProgramAs a simple example of a complete IMG program, consider the
    following. It gets an image, works out its mean value, and writes the
    value out: 
      SUBROUTINE MEAN( ISTAT )
C  Get the input image.
      CALL IMG_IN( 'IN', NX, NY, IP, ISTAT )
C  Derive the mean and write it out.
      CALL DOSTAT( %VAL( IP ), NX, NY )
C  Free the image.
      CALL IMG_FREE( 'IN', ISTAT )
      END
C  This routine does all the work.
      SUBROUTINE DOSTAT( IMAGE, NX, NY )
      REAL IMAGE( NX, NY )
      SUM = 0.0
      DO 1 J = 1, NY
         DO 2 I = 1, NX
            SUM = SUM + IMAGE( I, J )
 2       CONTINUE
 1    CONTINUE
      WRITE( *, * ) 'Mean = ', SUM / REAL( NX * NY )
      END
Note that the "program" is actually a subroutine with an INTEGER
    argument so that it can work with the Starlink Software Environment. To
    work with images of any size, it also uses the "%VAL" cheat to make the
    image look like an adjustable dimension array. A C ProgramHere is exactly the same program written in C: 
  void mean_( int *istat ) {
     float *ip, sum = 0.0f;
     int nx, ny, i;
     /*  Get the input image. */
     imgIn( "in", &nx, &ny, &ip, istat );
     /*  Derive the mean and write it out. */
     for ( i = 0; i < nx * ny; i++ ) sum += ip[ i ];
     printf( "Mean value = %f\n", sum / ( nx * ny ) );
     /*  Free the image. */
     imgFree( "in", istat );
  }
  In C, using a pointer to access the image is more natural, but on the
    other hand arrays cannot have adjustable dimensions as they can in
    Fortran. Accessing Different Data FormatsYou may have noticed that we haven't yet talked about data formats, and
    that's because to a large extent they aren't important. When your program asks for an image, IMG goes to great lengths to
    deliver exactly what you asked for. If the data aren't quite right, it
    converts them into the form you want. This may involve running a "driver"
    - a program which grants access to a particular data format, but you
    shouldn't need to worry about this because a selection of standard drivers
    is available simply by typing: 
    
% convert
     This command enables your IMG programs to access Figaro (.dst), IRAF
    and FITS files, plus a few others, in addition to the default Starlink NDF
    format. You could then run the "mean" program (above) and give it the name of a
    data file in any of these formats: 
    
% mean
IN - Input image > myimage
Mean = 108.3154
%
     Whichever format you have, the result is the same.  Only if you had the
    same file in two formats (say "myimage.sdf" and "myimage.imh") would you
    need to distinguish them by adding ".imh" to the name. In fact, this facility is not unique to the IMG library and is becoming
    available to many Starlink applications, most recently Figaro. For the
    more experienced programmer, who perhaps has data in a private format,
    this opens the possibility of writing a "driver" to allow existing
    Starlink software to operate on those data. Header ItemsOf course, most astronomical data have additional values associated
    with them in the form of "header items", and no description of data access
    would be complete without mentioning these. Characteristically, IMG makes
    it all very straightforward. For example, to read a header item you might use: 
    
CALL HDR_INR( 'IN', ' ', 'AIRMASS', 1, AIRMAS, STATUS )
hdrInf( "in", " ", "airmass", 1, airmass, status );
     Which would return the value of the AIRMASS header item (if one exists)
    for image "in". Writing header items is also simple: 
    
CALL HDR_OUT( 'OUT', ' ', 'OBSERVER', 'Our Hero', 'Captain Starlink', STATUS )
hdrOut( "out", " ", "OBSERVER", "Our Hero", "Captain Starlink", 0, status );
     Further ReadingA full description of the IMG library can be found in Starlink User
    Note 160 (SUN/160) This contains further details and instructions on how
    to link your programs which you should read before getting started. The more adventurous can discover how to provide access to new data
    formats by reading Starlink System Note 20 (SSN/20).
     |