Actual C code to write out a single plane

This is the actual C code5 to write out a plane file. The function write_plane takes as arguments, pointers to a PLANE structure, a PLANE_INFO structure, a string containing the associations list, and a string containing the name of the file to write. If the associations list string is a NULL pointer, the string "NIL" is written to the file as the associations list record.

  /*
   * write_plane(plane,plane_info,associations,filename) - 
   * write out a plane.
   */

write_plane(plane,plane_info,associations,filename)
PLANE *plane;
PLANE_INFO *plane_info;
char *associations;
char *filename;
{

First we declare local variables:

    static LLVS_PLANE_FILE_HEADER header;
    /* plane size header record structure */
    static LLVS_PLANE_SIZE_HEADER size_header;
    int plsize;                 /* # bytes in plane */
    FILE *plfile;               /* plane file */
    unsigned char *data_pointer; /* pointer to data buffer */
    int rbytes, bytesleft;      /* I/O byte counters */

Now we open the plane file and setup the plane file header record. The byte sex and float format fields are set to the values ``native'' to the current machine. write_plane does not convert the data to any particular format.

    /* open file.  abort if open failure */
#ifdef VMS
    plfile = fopen(filename,"w", "rfm=var");
#else
    plfile = fopen(filename,"w");
#endif
    if (plfile == NULL) return(-1);
    /* fill in plane file header record */
    header.ptype = plane_info->datatype;
    header.bsex = LLVS_NATIVE_BYTE_SEX;
    header.floatfmt = LLVS_NATIVE_FLOATFMT;
    header.reserved = 0;
    header.pl_level = plane_info->level;
    header.row_location = plane_info->row_location;
    header.col_location = plane_info->column_location;
    header.background.iback = plane_info->background.fixnum;
    header.data_length = plane_size(plane_info) + 12;
    if (associations == NULL) associations = "NIL";
    header.alist_length = strlen(associations);
    header.multi_plane_flag = 0;

Now write the header record:

    /* write header record */
    if (fwrite(&header,32,1,plfile) != 1) return(-1);
    /* compute plane size (for use later) */
    plsize = header.data_length - 12;

Now write out the associations list:

    /* get pointer to associaions list */
    data_pointer = (llvs_ubyte *) associations;
    /* and length */
    bytesleft = header.alist_length;
    /* write out associations list */
    while (bytesleft > 0) {
        rbytes = bytesleft;
        if (rbytes > BLOCKSIZE) rbytes = BLOCKSIZE;
        if (fwrite(data_pointer,rbytes,1,plfile) != 1) 
            return(-1);
        data_pointer += rbytes;
        bytesleft -= rbytes;
        }

Now fill in and write out the size header record:

    /* fill in size header */
    size_header.datatype_again = header.ptype;
    size_header.row_dimension = plane_info->row_dimension;
    size_header.col_dimension = plane_info->column_dimension;

    /* write out size header */
    if (fwrite(&size_header,12,1,plfile) != 1) return(-1);

Finally write out the plane's pixels:

    /* get pointer & size of plane data */
    data_pointer = (unsigned char *) plane->plane_base;
    bytesleft = plsize;
    /* write plane data */
    while (bytesleft > 0) {
        rbytes = bytesleft;
        if (rbytes > BLOCKSIZE) rbytes = BLOCKSIZE;
        if (fwrite(data_pointer,rbytes,1,plfile) != 1) 
            return(-1);
        data_pointer += rbytes;
        bytesleft -= rbytes;
        }

And close the file when we are done.

    /* close file */
    fclose(plfile);
    return(0);
    }

This little function is used to compute the size of the plane in bytes.

 /* compute plane size from plane info */

plane_size(plinfo)
PLANE_INFO *plinfo;
{
    int elements;               /* element count */

    elements = plinfo->row_dimension * 
               plinfo->column_dimension;
    switch (plinfo->datatype) {
        case LLVS_BIT: return( (elements + 7) / 8);
        case LLVS_BYTE:
            return( elements * sizeof(unsigned char));
        case LLVS_SHORT: 
            return( elements * sizeof(short int));
        case LLVS_INT: 
            return( elements * sizeof(long int));
        case LLVS_FLOAT: 
            return( elements * sizeof(float));
        }
    }