SLC(2)

NAME
SLC File Format - The SLC file format for use in the VolVis system

DESCRIPTION
The VolVis system can handle various data input types. One such type is the SLC file format. This format should be used to load volumetric data into the VolVis system. In Version 1.0 of the system, only 3D arrays of unsigned characters can be utilized. In future releases, integer and floating point arrays will also be allowed. The SLC file format is as follows:
 byte size name description
 ----------------------------------------------

 0 int magic magic number used to
                        verify that this is
                        an slc file
 4 int x_voxels number of samples in the
                        x dimension
 8 int y_voxels number of samples in the
                        y dimension
 12 int z_voxels number of samples in the
                        z dimension
 16 int bits number of bits per sample
                        point
 20 float x_units distance between two
                        neighboring samples values
                        in the x direction
 24 float y_units distance between two
                        neighboring samples values
                        in the y direction
 28 float z_units distance between two
                        neighboring samples values
                        in the z direction
 32 C_UnitType unit_type the unit type
                        (e.g. millimeter, inch)
 36 C_DataOrigin origin        where the data came
                        from (e.g. MRI, CT )
 40 C_DataModification mod is this the original data,
                        or has it been, for
                        example, resampled or
                        filtered
 44 C_CompressionType comp the type of compression used
                        on the data
 48 C_Byte data the data = x_voxels *
                        y_voxels * z_voxels
                        data sample, where each sample
                        is bits number of bits.
                        If there is no compression
                        then this is stored here
                        directly, otherwise a
                        compressed form of the data
                        is stored here.

The first three values, x_voxels, y_voxels, and z_voxels, describe the size of the data in actual samples. The next value, bits, is the number of bits per data sample. This value may be 8, 16, or 32 currently. The next three values, x_units, y_units, and z_units, describe the spacing of the samples in units, where the unit type is indicated by the eighth value, unit_type. For example, a typical data set may have 256 samples in the x direction, 256 samples in the y direction and 128 samples in the z direction. The distance between samples in the x and y directions may be 1.25, while the distance between samples in the z direction may be 2.5. So even though there are twice as many samples in the x and y directions as there are in the z direction, the data is the same size in units in all three directions. The unit type may be C_METER_UNIT, C_MILLIMETER_UNIT, C_MICRON_UNIT, C_FOOT_UNIT, or C_INCH_TYPE. The origin of the data is given by origin, and may indicate, for example, that this data came from a BioRad confocal microscope. The mod header value is used to keep track of modification made to this data set. For example, this value would indicate whether this is the original data, or if the data has been filter, resampled, or both. Finally, the compression type comp indicate the type of compression, if any, which was applied to the data that follows. C_UnitType, C_DataOrigin, C_DataModification, and C_CompressionType are all defined in the ${VOLVIS_HOME}/include/C_enums.h include file. The format of the data that follows the header is dependent upon the compression type. If no compression is used, and the data is 8 bits per sample, then following the header information is x_voxels*y_voxels*z_voxels bytes, which are the data samples. These samples are stored with the x index changing fastest and the z index changing slowest. Essentially, the data is stored in the same way C would store the array data[z_voxels][y_voxels][x_voxels] in memory. The following code segment could be used to read an SLC file where no data compression was used:
        #include "C_volvis.h"
        int    x_voxels, y_voxels, z_voxels;
        float    x_units,  y_units,  z_units;
        int bits;
        int magic;
        C_DataOrigin origin;
        C_DataModification mod;
        C_CompressionType comp;
        int fd, data_size;
        C_Byte voxel_ptr;
        C_UnitType unit_type;
        fd = open( filename, O_RDONLY );
        /* Read In Header Information */
    read( fd, &magic, sizeof(int) );
        read( fd, &x_voxels, sizeof(int) );
        read( fd, &y_voxels, sizeof(int) );
        read( fd, &z_voxels, sizeof(int) );
    read( fd, &bits, sizeof(int) );
        read( fd, &x_units, sizeof(float) );
        read( fd, &y_units, sizeof(float) );
        read( fd, &z_units, sizeof(float) );
        read( fd, &unit_type, sizeof(C_UnitType) );
        read( fd, &origin, sizeof(C_DataOrigin) );
        read( fd, &mod, sizeof(C_DataModification) );
        read( fd, &comp, sizeof(C_CompressionType) );
    if ( comp == C_NO_COMPRESSION )
    {
            /* Malloc Space For Data And Read It In*/
            data_size = x_voxels * y_voxels * z_voxels;
            voxel_ptr = (C_Byte *) malloc( data_size * sizeof(C_Byte) );
            read( fd, &voxel_ptr, data_size * sizeof(C_Byte) );
    }
        close( fd );

The following code segment could be used to write an SLC file with no data compression:
        #include "C_volvis.h"
        int    x_voxels, y_voxels, z_voxels;
        float    x_units,  y_units,  z_units;
        int    fd, data_size;
        int magic;
        C_DataOrigin origin;
        C_DataModification mod;
        C_CompressionType comp;
        C_Byte    voxel_ptr;
        C_UnitType    unit_type;
        fd = open( filename, O_WRONLY | O_CREAT );
    magic = C_SLC_MAGIC;
    origin = C_BIORAD_CONFOCAL;    /* (for example) */
    mod = C_ORIGINAL_DATA;    /* (for example) */
    comp = C_NO_COMPRESSION;
        /* Write The Header Information */
        write( fd, &magic, sizeof(int) );
        write( fd, &x_voxels, sizeof(int) );
        write( fd, &y_voxels, sizeof(int) );
        write( fd, &z_voxels, sizeof(int) );
        write( fd, &bits, sizeof(int) );
        write( fd, &x_units, sizeof(float) );
        write( fd, &y_units, sizeof(float) );
        write( fd, &z_units, sizeof(float) );
        write( fd, &unit_type, sizeof(C_UnitType) );
        write( fd, &origin, sizeof(C_DataOrigin) );
        write( fd, &mod, sizeof(C_DataModification) );
        write( fd, &comp, sizeof(C_CompressionType) );
        /* Write The Data */
        data_size = x_voxels * y_voxels * z_voxels;
        write( fd, &voxel_ptr, data_size * sizeof(C_Byte) );
        close( fd );

If run length encoding is used to compress the data, then the run length encoding algorithm described in C_encode_8bit_data, C_encode_16bit_data and C_encode_32bit_data is used on a slice by slice basis, writing to the file the size of the compressed slice, then the slice, for each slice of the data.

SEE ALSO
FUN, IMG, TXT, C_write_SLC_file, C_read_SLC_file, C_encode_8bit_data, C_encode_16bit_data, C_encode_32bit_data

AUTHOR
    Lisa Sobierajski