C USING IMG FROM C

 C.1 IMG C functions
 C.2 HDR C functions
 C.3 Examples of using IMG from C
 C.4 Examples of using HDR from C
 C.5 Compiling and linking C programs

C functions, that are equivalent to the Fortran subroutines, are available for those who prefer this language (indeed using IMG from C can seem more natural as IMG returns pointers to data). The major changes in the interface (compared with the Fortran specifications) are that the names of functions change from img_something or hdr_something to imgSomething and hdrSomething and that “strings” which are returned or can be passed as arrays also have a length argument.

C.1 IMG C functions

void imgCancl (char *param, int *status)
Cancel an image/parameter association
void imgDelet (char *param, int *status)
Delete an image
void imgFree (char *param, int *status)
Free an image
void imgIn[N][X] (char *param, int *nx, [int *ny,] [int *nz,] TYPE **ip, int *status)
Access an existing image for reading
void imgIndf (char *param, int *indf, int *status)
Obtain an NDF identifier for an image
void imgMod[N][X] (char *param, int *nx, [int *ny,] [int nz,] TYPE **ip, int *status)
Access an image for modification
void imgName[N][X] (char *param, char *value, int value_length, int *status)
Return the image name
void imgNew[N][X] (char *param, int nx, [int ny,] [int nz,] TYPE **ip, int *status)
Create a new image
void imgOut[X] (char *param1, char *param2, TYPE **ip, int *status)
Create an output image
void imgTmp[N][X] (char *param, int nx, [int ny,] [int nz,] TYPE **ip, int *status)
Create a temporary image

Where the parts in "[]" are optional or not always available. [N] indicates the number of dimensions of the data you want to access and the necessary nx, ny and nz arguments should be passed.



Number of dimensions [N] nx, ny & nz required


1 nx
2 nx & ny
3 nx, ny & nz


The default number of dimensions are two (in which case do not replace [N] by anything).

The ordering of array dimensions is different in C to Fortran, so for instance the Fortran array ARRAY(NX,NY,NZ) is equivalent to the C array ARRAY[NZ][NY][NX], but usually this is of little importance since images are not of fixed sizes (so you’re unlikely to hard code any array dimensions) and you’re far more likely to use the data via a pointer to the first element. Since C arrays also always start at 0 (rather than 1 as is the default in Fortran) the index of an element say [y][x] is nx × y + x. In 3-D this becomes [z][y][x]nx × ny × z + nx × y + x.

The data type of the image is specified by replacing the [X] part of the name by one of the following character codes:




Character code [X] C data type (TYPE) Description



F float
D double
I int
S short
US unsigned short
B signed char Signed byte
UB unsigned char Unsigned byte



You will also need to replace TYPE by the related data type. The default data type is float (in which case do not replace [X] by anything and set TYPE to float).

C.2 HDR C functions

void hdrCopy ( char *param1, char *xname1, char *param2, char *xname2, int *status )
Copy header information from one image to another
void hdrDelet (char *param, char *xname, char *item, int comp, int *status)
Delete a header item
void hdrIn (char *param, char *xname, char *item, int comp, char *value,
    int value_length, int *status)

Read a character header item
void hdrInC (char *param, char *xname, char *item, int comp, char *value,
    int value_length, int *status)

Read a character header item
void hdrIn[X] (char *param, char *xname, char *item, int comp, TYPE *value,
    int *status)

Read a header item
void hdrMod (char *param, int *status)
Open an image allowing modification of any header items
void hdrName (char *param, char *xname, int n, char *item, int item_length,
    int *status)

Return a header item name
void hdrNumb (char *param, char *xname, char *item, int *n, int *status)
Return a header item count
void hdrOut (char *param, char *xname, char *item, char *commen, char *value,
    int value_length, int *status)

Write a character header item
void hdrOutC (char *param, char *xname, char *item, char *commen, char *value,
    int value_length, int *status)

Write a character header item
void hdrOut[X] (char *param, char *xname, char *item, char *commen, TYPE *value,
    int *status)

Write a header item

Where the "[X]" indicate the data type of the header items. The possible values of [X] are:



Character code[X] C data type (TYPE) Description



C char Character string
D double
I int
L int Boolean
F float



C.3 Examples of using IMG from C

C.3.1 Accessing an existing image

This section shows a C version of the mean program from §2.1.

  #include <stdio.h>
  #include "img.h"                                              [1]
  
  void mean_(int *istat)                                        [2]
  {
    /* Local variables: */
    float *ip, sum;
    int nx, ny, i;
  
    /*  Access the input image. */
    imgIn( "in", &nx, &ny, &ip, istat );
  
    /*  Derive the mean and write it out. */
    sum = 0.0f;
    for( i=0; i < nx*ny; i++ ) sum += ip[i];
    printf ("Mean value = %f\n", sum/(nx*ny) );
  
    /*  Free the input image. */
    imgFree( "in", istat );
  }

The following notes refer to the numbered statements:

(1)
The file img.h contains prototypes of all the IMG and HDR functions.
(2)
As in the Fortran case this program needs to be created as a function with an int * argument. This is a replacement for the main function. Note that the function is named the same as the eventual program except for the trailing underscore. The underscore is required as this function will be called from a Fortran subroutine (you should also note that this “trick” may not be the same from machine to machine, to do this portably you should use the CNF (SUN/209) macros as in the full example of mean.c).

As before an interface file - mean.ifl - is also required to complete the program.

C.3.2 Creating a new image

This example (flat.c) shows how to create a new image. It also sets all the elements of the image to 1.0.

  #include <stdio.h>
  #include "img.h"
  
  void flat_(int *istat)
  {
  
  
    /*  Local variables: */
    float *ip;
    int i;
  
    /*  Create a new image. */
    imgNew( "out", 416, 578, &ip, istat );
  
    /*  Set all its elements to the value 1.0. */
    for( i=0; i < 416*578; i++ ) {
      ip[i] = 1.0f;
    }
  
    /*  Free the new image. */
    imgFree( "out", istat );
  }

C.3.3 Modifying an image

This example shows how to access an existing image and modify its values.

     /* Access an existing image. */
     imgMod( "in", &nx, &ny, &ip, istat );
  
     /* Set all elements with a value above 32000 to 32000. */
     for( i=0; i <nx*ny; i++ ) {
         if ( ip[i] > 32000.0f ) {
            ip[i] = 32000.0f;
         }
     }
  
     /* Free the image */
     imgFree( "in", istat );

C.3.4 Modifying a copy of an image

This example (add.c) copies the input image and then modifies the copy.

    /*  Access an existing image */
    imgIn( "in", &nx, &ny, &ptrIn, status );
  
    /*  Copy this to an output image */
    imgOut( "in", "out", &ptrOut, status );
  
    /*  Get the value to add. */
    printf("Value to add to image: ");
    scanf( "%f", &value );
  
    /*  And do the work. */
    for( i=0; i <nx*ny; i++ ) {
      ptrOut[i] = value + ptrIn[i];
    }
  
    /*  Free the input and output images. */
    imgFree( "*", status );

C.3.5 Getting images as workspace

This example (shadow.c) shows how to create temporary images. The HDS (SUN/92) manual describes some reasons why you might consider using temporary images rather than “malloc’d” memory in your programs.

    /*  Access the input image. */
    imgIn( "in", &nx, &ny, &ipin, istat );
  
    /*  Get a same sized temporary image as workspace. */
    imgTmp( "temp", nx, ny, &iptemp, istat );
  
    /*  Free all images (this deletes the temporary image). */
    imgFree( "*", istat );

C.3.6 Using “images” which are not 2-dimensional

This section just shows some example calls that access spectra and data-cubes.

     imgIn1( "spectrum", &nx, &ip, istat );
     imgIn3( "cube", &nx, &ny, &nz, &ip, istat );

C.3.7 Accessing images using different data types

So far all the example shown access the image data assuming a type of float. IMG can also access data in other useful types. A list of these is shown in §C.1. Among the possible calls are:

     double *dPtr;
     imgInD( "image", &nx, &ny, &dPtr, istat );
     float *fPtr;
     imgInF( "image", &nx, &ny, &fPtr, istat );
     short *sPtr;
     imgInS( "image", &nx, &ny, &sPtr, istat );
     int *iPtr;
     imgInI( "image", &nx, &ny, &iPtr, istat );

Requirements for data types and dimensionalities can be mixed as in:

     imgIn1D( ’spectrum’, &nx, &ip, istat )
     imgMod2I( ’image’, &nx, &ny, &ip, istat )
     imgNew3S( ’cube’, &nx, &ny, &nz, ip, istat )
     imgIn2F( ’image’, &nx, &ny, &ip, istat )

C.3.8 Accessing multiple images

This example (proc.c) shows how IMG can access more than one image per function call:

     /*  Declare pointers for images. */
     float *ip[3], *ipproc, *ipbias, *ipflat, *ipraw ;              [1]
     int nx, ny, i;
  
     /*  Access input images. */
     imgIn( "bias,flat,raw", &nx, &ny, ip, istat );                 [2]
     ipbias = ip[0];
     ipflat = ip[1];
     ipraw = ip[2];
  
     /*  Create a new output image by copying the raw input image. */
     imgOut( "raw", "proc", &ipproc, istat );
  
     /*  Debias and flatfield data. */
     for( i=0; i <nx*ny; i++ ) {
        *ipproc++ = ( *ipraw++ - *ipbias++ ) / *ipflat++;
     }
  
     /*  Free all the images.*/
     imgFree( "*", istat );

The following notes refer to the numbered statements:
(1)
Note that the variable ip is declared as an array of pointers to float.
(2)
After this call each of the elements of ip is set to point to a different image. The advantage of such a call is that all the images are guaranteed to be the same shape and data type.
C.3.9 Handling “bad” data

The way that you handle “bad” values in your data is similar to that used in Fortran, see §4.1.6, however, the bad data values themselves are now defined in the img.h file and have names to reflect the C data types.




Bad value macro C data type



VAL__BADF float
VAL__BADD double
VAL__BADI int
VAL__BADS short
VAL__BADUS unsigned short
VAL__BADB signed char
VAL__BADUB unsigned char



C.4 Examples of using HDR from C

C.4.1 Reading header items

This example (hdrread.c) shows how to read the value of a header item.

  
    /*  Local Variables: */
    char item[] = "OBSERVER";
    char value[40];                                 [1]
  
    /*  Try to read the value. */
    hdrIn( "in", " ", item, 1, value, 40, istat );  [2]
  
    /*  And write it out */
    printf( "This data was taken by %s.\n", value);
  
    /*  Free the image */
    imgFree( "in", istat );

The following notes refer to the numbered statements:
(1)
A character “string” is declared to contain the value of the header item.
(2)
The size of the string is passed as an additional argument when calling hdrIn (this argument is not present in the Fortran version).
C.4.2 Writing header items

This example (hdrwrite.c) shows how to write a header item to an image.

    /*  Write the header item. */
    hdrOut( "out", " ", "OBSERVER", "The observer.", "Fred Bloggs", 0, istat ); [1]
  
    /*  Free the image. */
    imgFree( "out", istat );

The following notes refer to the numbered statements:
(1)
Note the extra argument which is set to 0. This indicates that a single string ("Fred Bloggs") has been passed. This could also have been set to the value 12, the string length. This argument is of more significance when dealing with multiple images.
C.4.3 Accessing header items using different data types

All the possible types of header items that can be accessed are described in §C.2. Among the possible calls are:

     float bscale;
     hdrInF( "in", " ", "bscale", 1, &bscale, istat );
     int ibfact;
     hdrInI( "in", " ", "binned", 1, &ibfact, istat );
     #define TRUE 1
     hdrOutL( "out", " ", "checked",  "Data checked for C/Rs", TRUE, istat );

C.4.4 Accessing header items by index

This example (hdrlist.c) shows how to access header items by index.

    /*  Local Variables: */
    char value[80], item[30];
    int nitem, i;
  
    /*  See how many items are present (this also accesses the image). */
    hdrNumb( "in", " ", "*", &nitem, istat );
    for( i=1; i<=nitem; i++ ) {
  
      /*  Get the name of the I’th header item. */
      hdrName( "in", source, i, item, 30, istat );                     [1]
  
      /*  Get its value and print out the item name and value. */
      hdrInC( "in", source, item, 1, value, 80, istat );               [1]
      printf( "%s = %s \n", item, value );
    }

The following notes refer to the numbered statements:
(1)
Note the extra arguments (30 & 80) that pass the maximum length of the output strings.
C.4.5 Reading and writing header items from/to many images

It is possible to read and write header items from/to many images in one call and some examples follow. Note that arrays of strings can only be passed using fixed string length. It is not possible to use arrays of pointers to char forming a ragged array. When using a character array you should pass a pointer to the first element not the actual array (as the HDR routines expect to see char *).

This example shows how to read the same header item from two images at the same time.

     char RA[2][80];
     char DEC[2][80];
     hdrIn( "IN1,IN2", " ", "RA", 1, (char *) RA, 80, status );         [1]
     hdrIn( "IN1,IN2", " ", "DEC", 1, (char *) DEC, 80, status );       [1]
     printf( "The RA and DEC of IN1 are: %s, %s\n", RA[0], DEC[0] );
     printf( "and the RA and DEC of IN2 are: %s, %s\n", RA[1], DEC[1] );
     imgFree( "*", status );

The following notes refer to the numbered statements:
(1)
The address to the first element of the RA and DEC arrays is passed. This could have been written as &RA[0][0] and &DEC[0][0].

This example shows how to write values to the same header item of two images.

     char obstype[2][5] = {"BIAS","FLAT"};
     hdrOut( "BIAS,FLAT", " ", "OBSTYPE", "Type of observation",
             (char *) obstype, 5, istat );
     imgFree( "*", istat );

C.5 Compiling and linking C programs

Compiling and linking a C program is very similar to the methods described (in §6), except that you must compile the source code before the linking stage.

If your program source file is named prog.c, and it only depends on IMG, then the commands:

  % cc -c -I/star/include prog.c
  % alink prog.o -L/star/lib ‘img_link_adam‘

will compile the source and link the program.