HTML automatically generated with rman
Table of Contents


image - binary format for 2D and 3D image/cube "ccd" files


#include <stdinc.h>
#include <filestruct.h>
#include <image.h>


image implement a rectangular 2-dimensional matrix or 3-dimensional cube in a filestruct(5NEMO) datafile. The current implementation restricts images to well known 2- and 3-dimensional cases, as well as the restriction that the whole image must be in memory. See mdarray(3NEMO) for a more general multi-dimensional array interface (though there is no special I/O interface for this data structure). The coordinate transformation to world coordinates is by no means restricted to a simple linear equation of the form:
        x.w.c. = SCALE * i + OFFSET
where i runs from 0 to N-1, the dimension of the matrix in any of its coordinates.

Image files are used in 2D and 3D images, i.e. a matrix of values of any kind (intensity, velocity etc.). The output format of image(3NEMO) files is the general binary structured fileformat as described in filestruct(3NEMO) .

The data is stored on disk in Fortran (column-major) or C (row-major) fashion, as in Data(row,column,plane) depending on a compile switch or #define in the image.h module, which must be included in every program using images. The default compilation is using the FORDEF, i.e. x coordinate running fastest in memory (compatibility with existing contour and FITS routines).


typedef struct {
    real   *frame;     /* pointer to datablock */
    real   **matrix;     /* 2D special case: pointers to pointers */
    real   ***cube;      /* 3D special case: ptr to ptr to ptr’s  */
    int    axis;         /* axis type (0=old, no ref pixel; 1=with Xref
    int    nx;         /* number of pixels along x-axis */
    int    ny;         /* number of pixels along y-axis */
    int    nz;           /* number of pixels along z-axis */
    real   xmin;     /* x-value belonging to reference x-pixel */
    real   ymin;     /* y-value belonging to reference y-pixel */
    real   zmin;     /* z-value belonging to reference z-pixel */
    real   dx;         /* step in x-pixel */
    real   dy;         /* step in y_pixel */
    real   dz;         /* step in z_pixel */
    real   xref;         /* reference pixel in X (0 the first) */
    real   yref;         /* reference pixel in Y */
    real   zref;         /* reference pixel in Z */
    real   map_min;     /* minimum map value */
    real   map_max;    /* maximum map value */
    int    beamtype;        /* type of beam used for beam smoothing */
    real   beamx;        /* beamwidth along x (if used) */
    real   beamy;        /* beamwidth along y (if used) */
    real   beamz;        /* beamwidth along z (if used) */
    string namex;        /* pointer to x-axis name string */
    string namey;        /* pointer to y-axis name string */
    string namez;        /* pointer to z-axis name string */
    string unit;
    real   time;
    string storage;        /* pointer to storage fashion string */
} image, *imageptr;


Accessing the individual structure components can be done through some pre-define macros (in image.h):
#define Frame(iptr)    ((iptr)->frame)
#define Nx(iptr)    ((iptr)->nx)
#define Ny(iptr)    ((iptr)->ny)
#define Nz(iptr)    ((iptr)->nz)
#define Axis(iptr)    ((iptr)->axis)
#define Xmin(iptr)     ((iptr)->xmin)
#define Ymin(iptr)     ((iptr)->ymin)
#define Zmin(iptr)     ((iptr)->zmin)
#define Dx(iptr)    ((iptr)->dx)
#define Dy(iptr)    ((iptr)->dy)
#define Dz(iptr)    ((iptr)->dz)
#define Xref(iptr)     ((iptr)->xref)
#define Yref(iptr)     ((iptr)->yref)
#define Zref(iptr)     ((iptr)->zref)
#define MapMin(iptr)    ((iptr)->map_min)
#define MapMax(iptr)    ((iptr)->map_max)
#define BeamType(iptr)    ((iptr)->beamtype)
#define Beamx(iptr)    ((iptr)->beamx)
#define Beamy(iptr)    ((iptr)->beamy)
#define Beamz(iptr)    ((iptr)->beamz)
#define Namex(iptr)    ((iptr)->namex)
#define Namey(iptr)    ((iptr)->namey)
#define Namez(iptr)    ((iptr)->namez)
#define Unit(iptr)      ((iptr)->unit)
#define Storage(iptr)   ((iptr)->storage)
/* row major */
#if defined(CDEF)
#define MapValue(iptr,ix,iy)    (*( (iptr)->frame + iy + ix*Ny(iptr) ))
#define CubeValue(iptr,ix,iy,iz)    (*( (iptr)->frame + iz + Nz(iptr)*(iy + Ny(iptr)*ix)))
/* column major */
#if defined(FORDEF)
#define MapValue(iptr,ix,iy)     (*( (iptr)->frame + ix + Nx(iptr)*iy) )
#define CubeValue(iptr,ix,iy,iz)    (*( (iptr)->frame + ix + Nx(iptr)*(iy+Ny(iptr)*iz)))

Array Notation

The MapValue and CubeValue macros are sometimes cumbersome typography, and using two image library routines, map2_image and map3_image these can be converted to the commonly used array syntax:
    image *iptr = open_image(....);
    real **a = map2_image(iptr);
    for (i=0; i<nx; i++)
        for (j=0; j<nx; j++)
            a[i][j] = 0.0;

The following example creates a simple cube by which you can test the row-major and column-major implementations.

In CDef mode:

    % ccdmath "" cube0 "%x+10*%y+100*%z" 4,3,2
    % tsf cube0
    double MapValues[4][3][2] 0.00000 100.000 10.0000 110.000 20.0000 120.000
...  123.000
In ForDef mode:
    % tsf cube0
    double MapValues[4][3][2] 0.00000 1.00000 2.00000 3.00000 10.0000 11.0000
... 123.000


The current default images (axis=0) have their original at the first (lower-left = 0,0) pixel. In FITS parlance, there is no freedom in the location of the reference pixel, it’s (0,0). For axis=1 (most programs now support it, notably ccdfits(1NEMO) and fitsccd(1NEMO) ) this limitation will go away, but only simple cartesian coordinate systems are supported. There is no astronomical WCS support, other than labeling it. Perhaps this will be for a future axis=2.

Future Expansions

Code could be modified to use dynamem(3NEMO) . Allows more flexable use by addressing image[i][j] instead of slower (?) macros MapValue(iptr,i,j)

See Also

snapshot(5NEMO) , image(3NEMO) , tsf(1NEMO) , mdarray(3NEMO)


Peter Teuben


~/src/pjt/image       image.c image.h image.3 image.5

Update History

29-Jun-87    V1.0: Original created    PJT
30-Jun-87    V2.0: use struct as interface    PJT
22-May-88    comment to use dynamem(3NEMO)    PJT
23-dec-88    V2.3: velocity added to header    PJT
18-jan-89    V3.0: 3D added PJT
1-feb-89    V4.0: compile switch for FORDEF and CDEF matrix storage    PJT
21-feb-00    A[i][j] usage            PJT
19-may-03    improved documentation    PJT
8-may-04    V5.0: added reference pixel for axis type 1    PJT
7-may-13    added benchmark example
27-jan-2021    noted axis=1 now becoming standard    PJT

Table of Contents