Previous: Pixel Sizes Up: Data Types and Host Representations Next: Dealing with Binary Labels

Converting Data Types & Hosts

This section describes how to convert data between different data types and hosts, when the RTL does not do it for you. Most of the time, the RTL will take care of any data type and host conversions automatically. There are times, however, when you will need to do your own conversions.

The translation routines have two parts: the setup routines, and the actual translation routine. The setup routines must be called first, to set up a user-supplied buffer that describes the translation. The translation routine may then be called as many times as necessary to do the actual translation.

It is important to note that you can have as many translation buffers active at the same time as you wish. They can be set up ahead of time, then used whenever they need to be in the program. This is illustrated in the example below.

There is really only one setup routine internally, which requires the data type, integer format, and real format for both the source and the destination. Since it is unwieldy to specify all six parameters every time something needs translating, there are five setup routines that provide part of the information for you. They are all simply syntactic sugar for the internal setup routine. These five are x/ zvtrans_set, x/ zvtrans_in, x/ zvtrans_inu, x/ zvtrans_inb, and x/ zvtrans_out. See the subroutine descriptions in Section , Translation Routines, for details on each routine.

The question arises of where do these six parameters come from? Either the source or the destination will be in the native host representation, so only the foreign machine need be specified. For x/ zvtrans_set, both source and destination are the local machine. The information for the foreign machine will usually come from the label of the file being read. This is made easier by the x/ zvtrans_inu routine. For binary labels (which may be from a different host type than the image), x/ zvtrans_inb can be used to get the binary label host information. On occasion, you may make use of the x/ zvhost routine to get the INTFMT and REALFMT for a machine, given the type of machine. This allows the user to specify that the file be written in a foreign format. Although this is not the usual mode of operation for VICAR, it is allowed.

An example should help to clarify things. A file is being read which contains a structure of mixed data type. The structure needs to be converted to the native format so it can be processed. The structure could come from the binary label of the file, or it could be the data in an old-style IBIS file. It doesn't even have to be a VICAR file - the translation routines don't care. The code below is partially C code and partially pseudocode. It would have to be fleshed out to compile or run.

/* Structure format: An int followed by two reals and an array of 8 shorts */

struct { int type; float coord[2]; short int values[8]; } data; unsigned char *old_ptr;

static int short_conv[12], int_conv[12], real_conv[12]; /* Translation bufs */ static int short_size, int_size, real_size; /* Pixel sizes for each type */

{ /* Begin here */

char intfmt[20], realfmt[20]; unsigned char input_buf[100];

zveaction("sa", ""); /* abort on error */

/*** Determine INTFMT and REALFMT, possibly via zvhost. ***/ /*** For a VICAR file, zvtrans_inu may be used instead. ***/ /*** For binary labels, zvtrans_inb may be used. ***/

/* Now set up the translation buffers. */

zvtrans_in(short_conv, "HALF", "HALF", intfmt, realfmt); zvtrans_in(int_conv, "FULL", "FULL", intfmt, realfmt); zvtrans_in(real_conv, "REAL", "REAL", intfmt, realfmt);

/* Get pixel sizes in the input file for each type */

zvpixsize(&short_size, "HALF", intfmt, realfmt); zvpixsize(&int_size, "FULL", intfmt, realfmt); zvpixsize(&real_size, "REAL", intfmt, realfmt);

/* The following could be in a read loop if desired. */

/*** Now the buffers are set up. Read the data into input_buf. ***/

old_ptr = input_buf;

zvtrans(int_conv, old_ptr, &data.type, 1); /* One integer */ old_ptr += int_size; zvtrans(real_conv, old_ptr, data.coord, 2); /* Two reals */ old_ptr += real_size*2; zvtrans(short_conv, old_ptr, data.values, 8); /* 8 shorts */ old_ptr += short_size*8;

} /* That's all! The data has been translated. */