/* VLib routines

* VLib - vector processing and utility library
* Please note saving date below:
* $Date: 2007/06/27 17:33:26 $

* A set of primitives for use in image processing. * c 1996-2002 Mark S. Cohen * * Please do not distribute without express permission of the author. * * Users making changes or extensions to this software are instructed * to notify the author of any such changes (in the interest of keeping * this material up to date and bug-free) * * The author makes no representation of the suitability of this software * for any particular purposes, nor does he certify the accuracy of the * algorithms provided. * * Please report any errors or bug fixes to mscohen@ucla.edu * * For academic use only. Commercial users should contact * Mark Cohen for licensing information. * * Keep track of the differences between vlen and npts as the description * of vector sizes. While vlen is supposed to be used to represent the * length of the input vector, npts is to represent the number of points * actually processed. Use might not be entirely consistent. * * Most of the routines that ask for an output vector cannot be used as * in-place operations. * ******************************************************************************* OSErr InitMessageLog ( void ) * Set up a file based message log for debugging and user support purposes ******************************************************************************* * LogMessage * Unified Error logging * * Requires that a global * FILE *MessageLog; * * exist (i.e., in main() ) in order that logging can take place to * screen or to a dated weekly rotating file. Adds the contents of MessageString * to the log. * * OSErr LogMessage( char *MessageString ) * *********************************************************************** * Keep control of ImgLib revisions * void GetVLibVer( char *buff ) * * Returns the version number for VLib in buff * ******************************************************************************* * DBG * Handy debugging utility. * * void DBG ( char *msg ) * * Uses stdout to print debug statements. Increments a counter with each call * and displays the message string in the format: * **** 1: message **** * ******************************************************************************* * IsTrueorFalse * Return Boolean value as a string (true or false). * void IsTrueorFalse (Boolean b, char *s) * ******************************************************************************* * ReportDataType * Return the name of the input file type as a string * * char *ReportDataType( short data_type ) * ******************************************************************************* * PercentCount * * Used to indicate percent completion on console output * * Boolean PercentCount( // returns true if the percent has changed by stepSize * int count // event counter * int max // maximum number of events * int stepSize // what increment in percent change to display * int *ans ) // the current percent of completion ******************************************************************************* * SetTypeRange * Set outMin and outMax to equal the data range of the data_type; * * void SetTypeRange( float *outMax, float *outMin, short data_type ) * ******************************************************************************* * ShowError * Dump an error message to a log file. Assumes that the file has been opened. * * void ShowError ( OSErr error, char *where, char *msg) * ******************************************************************************* * errfopen * This function reports its own messages. Use ck_fopen for more standard approach * Checks for valid file names and returns appropriate error messages * A re-write of fopen with a small amount of error reportinf. No Mac equivalent. * ck_fopen is recommended for current and new projects * * FILE *errfopen( char *fname, char *mode ) * ******************************************************************************* * ck_fopen * * Checks for valid file names and returns appropriate error messages. * * OSErr ck_fopen( FILE **f, -- returns an open file to f * char *fname, -- file name to open * char *mode ) -- standard C file mode * ******************************************************************************* * ck_fwrite * A wrapper for fwrite that checks for completion and posts an * Error on failure. All arguments as in fwrite. * * OSErr ck_fwrite( void *data, size_t itemSize, size_t nmemb, FILE *f ) * ******************************************************************************* * ck_fread * A wrapper for fread that checks for completion and posts an * Error on failure * * OSErr ck_fread( void *data, size_t itemSize, size_t nmemb, FILE *f ) * ******************************************************************************* * ck_fclose * A wrapper for fclose that checks for completion * * OSErr ck_fclose( FILE *f ) * ******************************************************************************* * ck_malloc and ck_calloc * * Really just a replacement for malloc and calloc with a small * amount of error reporting. * * This is among the most crucial differences between MAC & UNIX -- * The MAC must use its own memory manager to be stable. In this * version, all memory errors are to be treated as FATAL! * * Ptr ck_malloc( long size, char *msg ) * Ptr ck_calloc( long number_of_objects, int size, char *msg ) * ******************************************************************************* * CreateTempFile * Open a temporary file for write and return its name * OSErr CreateTempFile( FILE *TempFile, char **itsName ) * * Typical calling sequence: * * char *TempName; * FILE *TempFile; * * error = CreateTempFile( &TempFile, &TempName ); * ILError( error, "creating temporary file" ); * * error = ck_fclose( TempFile ); * ******************************************************************************* * GetFileSize * Determine the length of a specified file * OSErr GetFileSize( long *filesize, -- the calculated file size * char *fname ) -- the file name (unaltered) ******************************************************************************* * ReadLastBytes * Read at the end of a file * OSErr ReadLastBytes( char *fname, char *buff, long nBytes ) ******************************************************************************* * LockHandleToPointer * Lock a handle and return a pointer to its data (Macintosh). * This is used to address memory using standard C constructs (e.g., ImgLib) * within the Mac memory management. * * OSErr LockHandleToPointer( Handle h, -- an active Handle * void **p, -- a pointer to use * SignedByte *state ) -- the handle state * ******************************************************************************* * ck_AllocateHandle * Unified memory allocation for handles. Whenever possible, make this call instead of calling NewHandle() directly. This will ensure that all is well. OSErr ck_AllocateHandle(long size, Handle *handleAddress) Requires: nothing Receives: desired size, pointer to Handle to store results Changes: nothing Returns: error value NOTE: does not check memory reserve (use EasyMallocateHandle for that) ******************************************************************************* * memFree * * OSErr memFree( void **theMem, char *msg ) * * Because of the differences in pointer handling between Mac * and unix environments, disposing of pointers requires a separate * routine for each system. This is it: * We zero the pointer as well, so that no one can point to la-la land. ******************************************************************************* * cpy_alloc * Copy memory addresses to new name, implemented as a special * function so that we can track it. * * OSErr cpy_alloc(void **destPtr, char *msg1, void *srcPtr, char *msg2) ******************************************************************************* * YorN * Yield a string (Yes or No) based on a boolean * * char *YorN( int( theFlag )) ******************************************************************************* * Boolean pcByteOrder() -- true if Little Endian * Boolean macByteOrder() -- true if Big Endian * Functions to determine the byte order on the present platform. ******************************************************************************* * lowerString * void lowerString( char *theString ) * * Force a string to lower case ******************************************************************************* * vmov * Copy the contents of invec to outvec, leaving invec intact. * vectors must be of same type! * * CALLING SEQUENCE * OSErr vmov( *invec, in_step1, *outvec, out_step, vlen, data_type ) * * INPUTS: *invec -- input vector * *outvec -- output vector * in_step -- rate to step through input vector * out_step -- rate to step through output vector * vlen -- number of data points to process * NOTE: calling routine must ensure that this doesn't exceed * the lengths of the input vectors * data_type -- standard UCLA data type from ImgLib.h * * OUTPUTS: returns contents of invec in outvec ******************************************************************************* * vfill * Fill a vector with a constant value * * CALLING SEQUENCE * OSErr vfill( *invec, fill, vlen, data_type ) * * INPUTS: *invec -- input vector * fill -- constant fill value * vlen -- number of data points to process * NOTE: calling routine must ensure that this doesn't exceed * the lengths of the input vectors * data_type -- standard UCLA data type from ImgLib.h * ******************************************************************************* * vfsmul * Multiply each element in the vector by a floating point scalar. * vector and scalar must be of same type! * May be used in place. * * CALLING SEQUENCE * OSErr vfsmul(void *src, int instep, void *dst, int ostep, * float scalar, long vlen, int data_type ) * * INPUTS: *src -- input vector * instep -- rate to step through vector * *dst -- destination vector * outstep -- rate to step through vector * scalar -- float scalar multiplier * vlen -- number of elements in input vector to process * data_type -- standard data type of vector and scalar from above * * OUTPUTS: Returns each element in the vector multiplied by a float. Follows * standard arithmetic rounding rules. * * This, and many following returns, require typecasting of the input vectors ******************************************************************************* * vsmul * Multiply each element in the vector by a scalar. * vector and scalar must be of same type! * May be used in place. * * CALLING SEQUENCE * OSErr vsmul(void *src, int instep, void *dst, int ostep, * void *scalar, long vlen, int data_type ) * * INPUTS: *src -- input vector * instep -- rate to step through vector * *dst -- destination vector * outstep -- rate to step through vector * *scalar -- pointer the scalar multiplier * vlen -- number of elements in input vector to process * data_type -- standard data type of vector and scalar from above * * OUTPUTS: Returns each element in the vector multiplied by a scalar * * This, and many following returns, require typecasting of the input vectors ******************************************************************************* * vadd * Add the elements in two vectors and place the sum in a third. * All vectors must be of the same type! * * CALLING SEQUENCE * OSErr vadd ( void *invec1, int step1, void *invec2, int step2, * void *outvec, int out_step, long vlen, int data_type ) * * INPUTS: *invec1 and 2 -- input vectors * step -- rate to step through vectors * *outvec -- output vector * vlen -- number of data points to process * NOTE: calling routine must ensure that this doesn't exceed * the lengths of the input vectors * data_type -- standard data type of vector and scalar from above * * OUTPUTS: returns sum of invec1 and invec2 in outvec ******************************************************************************* * vsub * Take the difference of the elements in two vectors and place it in a third. * All vectors must be of the same type! * * CALLING SEQUENCE * OSErr vsub( void *invec1, int step1, void *invec2, int step2, * void *outvec, int out_step, long vlen, int data_type ) * * INPUTS: *invec1 and 2 -- input vectors * step -- rate to step through vectors * *outvec -- output vector * vlen -- number of data points to process * NOTE: calling routine must ensure that this doesn't exceed * the lengths of the input vectors * data_type -- standard data type of vector and scalar from above * * OUTPUTS: returns difference of invec1 and invec2 in outvec ******************************************************************************* * vmul * Multiply the elements in two vectors and place the product in a third. * All vectors must be of the same type! * * CALLING SEQUENCE * OSErr vmul( void *invec1, int step1, void *invec2, int step2, * void *outvec, int out_step, long vlen, int data_type ) * * INPUTS: *invec1 and 2 -- input vectors * step -- rate to step through vectors * *outvec -- output vector * vlen -- number of data points to process * NOTE: calling routine must ensure that this doesn't exceed * the lengths of the input vectors * data_type -- standard data type * * OUTPUTS: returns product of invec1 and invec2 in outvec ******************************************************************************* * vdiv * Divide the elements of numvec1 by denvec2 and place the ratio in outvec. * All vectors must be of the same type! * NOTE: RETURNS outvec[i] UNCHANGED IF denvec[i] IS 0 !!!! * * CALLING SEQUENCE * OSErr vdiv( void *numvec, int step1, void *denvec, int step2, * float *outvec, int out_step, long vlen, int data_type ) * * INPUTS: *numvec -- numerator vector * *denvec -- denominator vector * step -- rate to step through vectors * *outvec -- output vector * vlen -- number of data points to process * NOTE: calling routine must ensure that this doesn't exceed * the lengths of the input vectors * data_type -- standard data type of vector and scalar from above * * OUTPUTS: Returns error condition ******************************************************************************* * vminmax * * Determine the minimum and maximum in the vector. * CALLING SEQUENCE: * OSErr vminmax( void *invec, long vlen, void *vecmax, void *vecmin, int data_type ) * INPUTS: * invec -- properly typed input vector * vlen -- number of points in vector * data_type -- from #defines above * OUTPUTS: * vecmax, vecmin -- addresses of min and max outputs ******************************************************************************* * vfminmax * * Determine the minimum and maximum in the vector. * CALLING SEQUENCE: * OSErr vminmax( void *invec, long vlen, void *vecmax, void *vecmin, int data_type ) * INPUTS: * invec -- properly typed input vector * vlen -- number of points in vector * data_type -- from #defines above * OUTPUTS: * vecmax, vecmin -- addresses of min and max outputs as float ******************************************************************************* * vsqrt * Square root of each element of a vector in place. * * CALLING SEQUENCE * OSErr vsqrt( void *invec, int step, long vlen, int data_type ) * * INPUTS: *invec -- input vector * vlen -- input vector length * data_type -- standard data type from above * * OUTPUTS: returns square root (invec) in-place ******************************************************************************* * vsq * Square each element of a vector in place. * * CALLING SEQUENCE * OSErr vsq( void *invec, int step, long vlen, int data_type ) * * INPUTS: *invec -- input vector * vlen -- input vector length * data_type -- standard data type from above * * OUTPUTS: returns squared invec*invec in-place ******************************************************************************* * vssq * Return the sum of squares of a vector. Return is always a float. * Calling program should typecast if needed. * * CALLING SEQUENCE * double vssq( void *invec, int step, long vlen, int data_type ) * * INPUTS: *vec -- input vector * step -- rate to step through input vector * vlen -- length of input vector * data_type -- standard data type from above * * OUTPUTS: returns sum of all elements of invec*invec, stepping by step ******************************************************************************* * vsum * Return the sum all elements in a vector. Return is always a float. * Calling program should typecast if needed. * * CALLING SEQUENCE * double vsum( void *invec, int step, long vlen, int data_type ) * * INPUTS: *vec -- input vector * step -- rate to step throught input vector * vlen -- number of data points to process * data_type -- standard data type from above * * OUTPUTS: returns sum of all elements of vec, stepping by step ******************************************************************************* * vabs * Return the absolute value of each element in a vector. * * CALLING SEQUENCE * OSErr vabs( void *invec, int istep, void *ovec, int ostep, * long vlen, int data_type ) * * INPUTS: *vec -- input vector * step -- rate to step throught input vector * *outvec -- output vector * vlen -- number of data points to process * NOTE: calling routine must ensure that this doesn't exceed * the lengths of the input vectors * data_type -- standard data type of vector and scalar from above * * OUTPUTS: Error code ******************************************************************************* * vclr * Clear the contents of a vector * * CALLING SEQUENCE: * OSErr vclr(void * vec, long vlen, int data_type) * * INPUTS: vec -- vector of arbitrary data type * vlen -- number of bytes in vector * data_type -- standard UC data type * OUTPUTS: None ******************************************************************************* * get_datasize * Get the size (in bytes) of the local data types. * * CALLING SEQUENCE: * int get_datasize( -- returns the size in bytes * int data_type); -- accepts any of the UC standard types ******************************************************************************* * vbyteswap * Byte swapping utility for managing the order on DEC and Sun * * OSErr vbyteswap(void *invec, long vlen, int data_type) ******************************************************************************* * vbyteNswap * Byte swapping utility for items of known length * * OSErr vbyteNswap(void *invec, long vlen, short n_bytes) ******************************************************************************* * ConvertToPercent * Express invec as a percent change from refvec. If refvec is zero, output is zero * * OSErr ConvertToPercent( void *invec, -- pointer to input vector * void *refvec, -- pointer to reference vector * void *outvec, -- output vector * long vlen, -- total number of values to convert * int data_type ) -- take all comers * ******************************************************************************* * type_convert * Conversion between float, unsigned short and unsigned char * and, as of 6-18-02, signed short. * * Sets the error value if the conversion was non-trivial, and reports * the rules for use by the calling routine. * * OSErr type_convert( void *inData, -- pointer to original data * int inType, -- original data type * void *convertedData, -- pointer to converted data * int outType, -- converted data type * long nPts, -- total number of pixels to convert * float *fmax, -- calculated max and min of input data * float *fmin, * short *rules ) * * FUTURE: The rules for resolution and range scaling are passed in 'rules'. * Desired max and min of output are passed in fmax and fmin. ******************************************************************************* * Swapping for simple types: swI swF swS swUS swUI swD swL * Each swaps the original in place and returns the swapped value in place * * int swI( int *RevInt ) * float swF( float *RevFloat ) * short swS( short *RevShort ) * unsigned short swUS( unsigned short *RevUShort ) * unsigned int swUI( unsigned int *RevUInt ) * double swD( double *RevDouble ) * long swL( long *RevLong ) ******************************************************************************* MoveSwap MoveSwap moves data from Src to Dst, swapping the bytes, if requested OSErr MoveSwap( void *Src, // The location of a simple data type void *Dst, // output location for the data (swapped or unswapped) Boolean swap, // if true, swap byte order short data_type ) // standard data_type delcarator ******************************************************************************* * equalString * Test to see that two strings are equal, and return a Boolean * true if s1 and s2 are the same. false otherwise * * int equalString( char *s1, char *s2 ) ******************************************************************************* * CountWords * Count the number of words in a string. * * int CountWords( char *InputString, int *NumWords )