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)); } }