/*--------------------------------------------------------------------
 *    The MB-system:	mb_lgpl.c	9/13/2004
 *    $Id:  $
 *
 *    Copyright (c) 2004 by
 *    David W. Caress (caress@mbari.org)
 *      Monterey Bay Aquarium Research Institute
 *      Moss Landing, CA 95039
 *    and Dale N. Chayes (dale@ldeo.columbia.edu)
 *      Lamont-Doherty Earth Observatory
 *      Palisades, NY 10964
 *
 *    This file contains source code modified from source files
 *    distributed as part of MB-System. In contrast to the GPL-licensed
 *    MB-System distributions, the code contained here is licensed
 *    under the Lesser GNU Public license, or LGPL. This means that
 *    compiled versions of these functions, or functions derived from
 *    modifications to this code, may be linked with commercial
 *    applications without imposing any restriction on the sale and
 *    and distribution of those applications.
 *
 *    The full LGPL text may be accessed at http://www.gnu.org/
 *
 *    The release of this code under the LGPL does not change the
 *    the GPL licensing of any code contained in the regular
 *    MB-System distribution.
 *
 *    The source code provided here does not come with any warranties, 
 *    nor is it guarenteed to work on your computer or to do 
 *    anything useful. The user assumes full responsibility for 
 *    the use of this software. In particular, David W. Caress, 
 *    Dale N. Chayes, the Lamont-Doherty Earth Observatory of 
 *    Columbia University, the Monterey Bay Aquarium Research Institute, 
 *    or any other individuals or organizations involved in the 
 *    design and maintenance of the MB-System software package 
 *    and derived distributions are NOT responsible for any 
 *    damage that may follow from correct or incorrect use of this 
 *    source code. Moreover, it should be noted that the source
 *    code provided here has NOT been tested after modification
 *    from the related functions that are part of MB-System.
 *
 *    To access MB-System documentation or source code releases see:
 *         http://www.mbari.org/data/mbsystem
 *         http://www.ldeo.columbia.edu/MB-System
 *
 *--------------------------------------------------------------------*/
/*
 * Author:	D. W. Caress
 * Date:	September 13, 2004
 *
 * $Log:  $
 *
 *--------------------------------------------------------------------*/
/*
 *    The header file mb_lgpl.h contains structure and macro definitions
 *    required for this source to compile.
 *
 *    The function mblgpl_read_fbt() is intended to provide an
 *    an example template for reading swath bathymetry stored in
 *    "fbt" files as part of the MB-System processing environment.
 *
 *    An application using this function must have already opened the
 *    the fbt file (ergo the FILE pointer fp) and allocated the data
 *    storage structure referenced by store using mblgpl_fbt_alloc(). 
 *
 *
 */

/* standard include files */
#include <stdio.h>
#include <math.h>
#include <string.h>

/* mblgpl include file */
#include "mb_lgpl.h"

static char res_id[]="$Id:  $";

/*--------------------------------------------------------------------*/
int mblgpl_fbt_alloc(int verbose, struct mblgpl_fbt_struct **store_ptr, 
			int *error)
{
	char	*function_name = "mblgpl_fbt_alloc";
	int	status = MBLGPL_SUCCESS;
	struct mblgpl_fbt_struct *store;

	/* print input debug statements */
	if (verbose >= 2)
		{
		fprintf(stderr,"\ndbg2  MBLGPL function <%s> called\n",
			function_name);
		fprintf(stderr,"dbg2  Input arguments:\n");
		fprintf(stderr,"dbg2       verbose:    %d\n",verbose);
		fprintf(stderr,"dbg2       store_ptr:  %d\n",store_ptr);
		}

	/* allocate memory for data structure */
	status = mblgpl_malloc(verbose,sizeof(struct mblgpl_fbt_struct),
				store_ptr,error);
		
	/* get store */
	store = *store_ptr;

	/* initialize values in structure */
	store->kind = MBLGPL_DATA_NONE;
	store->lon2u = 0;
	store->lon2b = 0;
	store->lat2u = 0;
	store->lat2b = 0;
	store->year = 0;
	store->day = 0;
	store->min = 0;
	store->sec = 0;
	store->msec = 0;
	store->heading = 0;
	store->speed = 0;
	store->beams_bath = 0;
	store->beams_amp = 0;
	store->pixels_ss = 0;
	store->depth_scale = 0;
	store->distance_scale = 0;
	store->transducer_depth = 0;
	store->altitude = 0;
	store->beam_xwidth = 0;
	store->beam_lwidth = 0;
	store->spare = 0;
	store->beams_bath_alloc = 0;
	store->beams_amp_alloc = 0;
	store->pixels_ss_alloc = 0;
	store->beamflag = NULL;
	store->bath = NULL;
	store->bath_acrosstrack = NULL;
	store->bath_alongtrack = NULL;
	store->amp = NULL;
	store->ss = NULL;
	store->ss_acrosstrack = NULL;
	store->ss_alongtrack = NULL;
	memset(store->comment, 0, MBLGPL_FBT_COMMENTSIZE);

	/* print output debug statements */
	if (verbose >= 2)
		{
		fprintf(stderr,"\ndbg2  MBLGPL function <%s> completed\n",
			function_name);
		fprintf(stderr,"dbg2  Return values:\n");
		fprintf(stderr,"dbg2       *store_ptr: %d\n",*store_ptr);
		fprintf(stderr,"dbg2       error:      %d\n",*error);
		fprintf(stderr,"dbg2  Return status:\n");
		fprintf(stderr,"dbg2       status:     %d\n",status);
		}

	/* return status */
	return(status);
}
/*--------------------------------------------------------------------*/
int mblgpl_fbt_deall(int verbose, struct mblgpl_fbt_struct **store_ptr, 
			int *error)
{
	char	*function_name = "mblgpl_fbt_deall";
	int	status = MBLGPL_SUCCESS;
	struct mblgpl_fbt_struct *store;
	
	/* print input debug statements */
	if (verbose >= 2)
		{
		fprintf(stderr,"\ndbg2  MBLGPL function <%s> called\n",
			function_name);
		fprintf(stderr,"dbg2  Input arguments:\n");
		fprintf(stderr,"dbg2       verbose:    %d\n",verbose);
		fprintf(stderr,"dbg2       *store_ptr: %d\n",*store_ptr);
		}
		
	/* get store */
	store = *store_ptr;

	/* deallocate memory for data structures */
	status = mblgpl_free(verbose,&store->beamflag,error);
	status = mblgpl_free(verbose,&store->bath,error);
	status = mblgpl_free(verbose,&store->bath_acrosstrack,error);
	status = mblgpl_free(verbose,&store->bath_alongtrack,error);
	status = mblgpl_free(verbose,&store->amp,error);
	status = mblgpl_free(verbose,&store->ss,error);
	status = mblgpl_free(verbose,&store->ss_acrosstrack,error);
	status = mblgpl_free(verbose,&store->ss_alongtrack,error);

	/* deallocate memory for data structure */
	status = mblgpl_free(verbose,store,error);

	/* print output debug statements */
	if (verbose >= 2)
		{
		fprintf(stderr,"\ndbg2  MBLGPL function <%s> completed\n",
			function_name);
		fprintf(stderr,"dbg2  Return values:\n");
		fprintf(stderr,"dbg2       store_ptr:  %d\n",store_ptr);
		fprintf(stderr,"dbg2       error:      %d\n",*error);
		fprintf(stderr,"dbg2  Return status:\n");
		fprintf(stderr,"dbg2       status:     %d\n",status);
		}

	/* return status */
	return(status);
}
/*--------------------------------------------------------------------*/
int mblgpl_read_fbt(int verbose, FILE *fp, struct mblgpl_fbt_struct *store, int *error)
{
	char	*function_name = "mblgpl_read_fbt";
	int	status = MBLGPL_SUCCESS;
	int	read_size;
	short	*flag;
	int	header_length;
	char	buffer[MBLGPL_FBT_COMMENTSIZE];
	int	index;
	int	i;

	/* print input debug statements */
	if (verbose >= 2)
		{
		fprintf(stderr,"\ndbg2  MBLGPL function <%s> called\n",
			function_name);
		fprintf(stderr,"dbg2  Input arguments:\n");
		fprintf(stderr,"dbg2       verbose:    %d\n",verbose);
		fprintf(stderr,"dbg2       fp:         %d\n",fp);
		fprintf(stderr,"dbg2       store:      %d\n",store);
		}

	/* read next header id from file */
	if ((status = fread(buffer,1,2,fp)) == 2) 
		{
		status = MBLGPL_SUCCESS;
		*error = MBLGPL_ERROR_NO_ERROR;
		}
	else
		{
		status = MBLGPL_FAILURE;
		*error = MBLGPL_ERROR_EOF;
		}

	/* read rest of header from file */
	if (status == MBLGPL_SUCCESS)
		{
		flag = (short *) buffer;
		if (*flag == 8995)
			{
			store->kind = MBLGPL_DATA_COMMENT;
			header_length = MBLGPL_FBT_OLDHEADERSIZE;
			}
		else if (*flag == 25443)
			{
			store->kind = MBLGPL_DATA_COMMENT;
			header_length = 2;
			}
		else if (*flag == 28270)
			{
			store->kind = MBLGPL_DATA_DATA;
			header_length = MBLGPL_FBT_NEWHEADERSIZE;
			}
		else if (*flag == 25700)
			{
			store->kind = MBLGPL_DATA_DATA;
			header_length = MBLGPL_FBT_OLDHEADERSIZE;
			}
		else
			{
			status = MBLGPL_FAILURE;
			*error = MBLGPL_ERROR_UNINTELLIGIBLE;
			store->kind = MBLGPL_DATA_NONE;
			}
		}
	if (status == MBLGPL_SUCCESS
	    && header_length == 2)
		{
		/* only 2 byte header for new style comment */
		status = MBLGPL_SUCCESS;
		*error = MBLGPL_ERROR_NO_ERROR;
		}
	else if (status == MBLGPL_SUCCESS
	    && (status = fread(&buffer[2],1,header_length-2,
			fp)) == header_length-2)
		{
		status = MBLGPL_SUCCESS;
		*error = MBLGPL_ERROR_NO_ERROR;
		}
	else
		{
		status = MBLGPL_FAILURE;
		*error = MBLGPL_ERROR_EOF;
		}

	if (status == MBLGPL_SUCCESS && store->kind == MBLGPL_DATA_DATA)
		{
		index = 2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->year); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->day); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->min); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->sec); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->msec); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->lon2u); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->lon2b); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->lat2u); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->lat2b); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->heading); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->speed); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->beams_bath); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->beams_amp); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->pixels_ss); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->depth_scale); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->distance_scale); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->transducer_depth); index +=2;
		mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->altitude); index +=2;
		if (header_length == MBLGPL_FBT_NEWHEADERSIZE)
			{
			mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->beam_xwidth); index +=2;
			mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->beam_lwidth); index +=2;
			mblgpl_get_binary_short(MBLGPL_NO, (void *)  &buffer[index], &store->spare); index +=2;
			}
		}

	/* print debug statements */
	if (verbose >= 5)
		{
		fprintf(stderr,"\ndbg5  New header read in function <%s>\n",
			function_name);
		fprintf(stderr,"dbg5       flag:       %d\n",*flag);
		}
	if (verbose >= 5 && store->kind == MBLGPL_DATA_DATA)
		{
		fprintf(stderr,"dbg5       year:       %d\n",store->year);
		fprintf(stderr,"dbg5       day:        %d\n",store->day);
		fprintf(stderr,"dbg5       minute:     %d\n",store->min);
		fprintf(stderr,"dbg5       second:     %d\n",store->sec);
		fprintf(stderr,"dbg5       msec:       %d\n",store->msec);
		fprintf(stderr,"dbg5       lonu:       %d\n",store->lon2u);
		fprintf(stderr,"dbg5       lonb:       %d\n",store->lon2b);
		fprintf(stderr,"dbg5       latu:       %d\n",store->lat2u);
		fprintf(stderr,"dbg5       latb:       %d\n",store->lat2b);
		fprintf(stderr,"dbg5       heading:    %d\n",store->heading);
		fprintf(stderr,"dbg5       speed:      %d\n",store->speed);
		fprintf(stderr,"dbg5       beams bath: %d\n",
			store->beams_bath);
		fprintf(stderr,"dbg5       beams amp:  %d\n",
			store->beams_amp);
		fprintf(stderr,"dbg5       pixels ss:  %d\n",
			store->pixels_ss);
		fprintf(stderr,"dbg5       depth scale:%d\n",store->depth_scale);
		fprintf(stderr,"dbg5       dist scale: %d\n",store->distance_scale);
		fprintf(stderr,"dbg5       transducer_depth: %d\n",store->transducer_depth);
		fprintf(stderr,"dbg5       altitude:         %d\n",store->altitude);
		fprintf(stderr,"dbg5       beam_xwidth:      %d\n",store->beam_xwidth);
		fprintf(stderr,"dbg5       beam_lwidth:      %d\n",store->beam_lwidth);
		fprintf(stderr,"dbg5       spare:            %d\n",store->spare);
		fprintf(stderr,"dbg5       status:     %d\n",status);
		fprintf(stderr,"dbg5       error:      %d\n",*error);
		}

	/* read next chunk of the data */
	if (status == MBLGPL_SUCCESS 
		&& store->kind == MBLGPL_DATA_COMMENT)
		{
		read_size = MBLGPL_FBT_COMMENTSIZE;
		if ((status = fread(store->comment,1,read_size,fp))
			== read_size) 
			{
			status = MBLGPL_SUCCESS;
			*error = MBLGPL_ERROR_NO_ERROR;
			}
		else
			{
			status = MBLGPL_FAILURE;
			*error = MBLGPL_ERROR_EOF;
			}

		/* print debug messages */
		if (verbose >= 5 && status == MBLGPL_SUCCESS)
			{
			fprintf(stderr,"\ndbg5  New comment read in function <%s>\n",
				function_name);
			fprintf(stderr,"dbg5       comment: %s\n",store->comment);
			}
		}
	else if (status == MBLGPL_SUCCESS 
		&& store->kind == MBLGPL_DATA_DATA)
		{
		/* if needed reset numbers of beams and allocate 
		   memory for store arrays */
		if (store->beams_bath > store->beams_bath_alloc)
		    {
		    store->beams_bath_alloc = store->beams_bath;
		    if (store->beamflag != NULL)
			status = mblgpl_free(verbose, &store->beamflag, error);
		    if (store->bath != NULL)
			status = mblgpl_free(verbose, &store->bath, error);
		    if (store->bath_acrosstrack != NULL)
			status = mblgpl_free(verbose, &store->bath_acrosstrack, error);
		    if (store->bath_alongtrack != NULL)
			status = mblgpl_free(verbose, &store->bath_alongtrack, error);
		    status = mblgpl_malloc(verbose, 
				store->beams_bath_alloc * sizeof(char),
				&store->beamflag,error);
		    status = mblgpl_malloc(verbose, 
				store->beams_bath_alloc * sizeof(short),
				&store->bath,error);
		    status = mblgpl_malloc(verbose, 
				store->beams_bath_alloc * sizeof(short),
				&store->bath_acrosstrack,error);
		    status = mblgpl_malloc(verbose, 
				store->beams_bath_alloc * sizeof(short),
				&store->bath_alongtrack,error);

		    /* deal with a memory allocation failure */
		    if (status == MBLGPL_FAILURE)
			{
			status = mblgpl_free(verbose, &store->beamflag, error);
			status = mblgpl_free(verbose, &store->bath, error);
			status = mblgpl_free(verbose, &store->bath_acrosstrack, error);
			status = mblgpl_free(verbose, &store->bath_alongtrack, error);
			status = MBLGPL_FAILURE;
			*error = MBLGPL_ERROR_MEMORY_FAIL;
			if (verbose >= 2)
				{
				fprintf(stderr,"\ndbg2  MBLGPL function <%s> terminated with error\n",
					function_name);
				fprintf(stderr,"dbg2  Return values:\n");
				fprintf(stderr,"dbg2       error:      %d\n",*error);
				fprintf(stderr,"dbg2  Return status:\n");
				fprintf(stderr,"dbg2       status:  %d\n",status);
				}
			return(status);
			}
		    }
		if (store->beams_amp > store->beams_amp_alloc)
		    {
		    store->beams_amp_alloc = store->beams_amp;
		    if (store->amp != NULL)
			status = mblgpl_free(verbose, &store->amp, error);
		    status = mblgpl_malloc(verbose, 
				store->beams_amp_alloc * sizeof(short),
				&store->amp,error);

		    /* deal with a memory allocation failure */
		    if (status == MBLGPL_FAILURE)
			{
			status = mblgpl_free(verbose, &store->amp, error);
			status = MBLGPL_FAILURE;
			*error = MBLGPL_ERROR_MEMORY_FAIL;
			if (verbose >= 2)
				{
				fprintf(stderr,"\ndbg2  MBLGPL function <%s> terminated with error\n",
					function_name);
				fprintf(stderr,"dbg2  Return values:\n");
				fprintf(stderr,"dbg2       error:      %d\n",*error);
				fprintf(stderr,"dbg2  Return status:\n");
				fprintf(stderr,"dbg2       status:  %d\n",status);
				}
			return(status);
			}
		    }
		if (store->pixels_ss > store->pixels_ss_alloc)
		    {
		    store->pixels_ss_alloc = store->pixels_ss;
		    if (store->ss != NULL)
			status = mblgpl_free(verbose, &store->ss, error);
		    if (store->ss_acrosstrack != NULL)
			status = mblgpl_free(verbose, &store->ss_acrosstrack, error);
		    if (store->ss_alongtrack != NULL)
			status = mblgpl_free(verbose, &store->ss_alongtrack, error);
		    status = mblgpl_malloc(verbose, 
				store->pixels_ss_alloc * sizeof(short),
				&store->ss,error);
		    status = mblgpl_malloc(verbose, 
				store->pixels_ss_alloc * sizeof(short),
				&store->ss_acrosstrack,error);
		    status = mblgpl_malloc(verbose, 
				store->pixels_ss_alloc * sizeof(short),
				&store->ss_alongtrack,error);

		    /* deal with a memory allocation failure */
		    if (status == MBLGPL_FAILURE)
			{
			status = mblgpl_free(verbose, &store->ss, error);
			status = mblgpl_free(verbose, &store->ss_acrosstrack, error);
			status = mblgpl_free(verbose, &store->ss_alongtrack, error);
			status = MBLGPL_FAILURE;
			*error = MBLGPL_ERROR_MEMORY_FAIL;
			if (verbose >= 2)
				{
				fprintf(stderr,"\ndbg2  MBLGPL function <%s> terminated with error\n",
					function_name);
				fprintf(stderr,"dbg2  Return values:\n");
				fprintf(stderr,"dbg2       error:      %d\n",*error);
				fprintf(stderr,"dbg2  Return status:\n");
				fprintf(stderr,"dbg2       status:  %d\n",status);
				}
			return(status);
			}
		    }

		/* read bathymetry */
		read_size = sizeof(char)*store->beams_bath;
		status = fread(store->beamflag,1,read_size,fp);
		read_size = sizeof(short int)*store->beams_bath;
		status = fread(store->bath,1,read_size,fp);
		status = fread(store->bath_acrosstrack,1,read_size,fp);
		status = fread(store->bath_alongtrack,1,read_size,fp);

		/* read amplitudes */
		read_size = sizeof(short int)*store->beams_amp;
		status = fread(store->amp,1,read_size,fp);

		/* read sidescan */
		read_size = sizeof(short int)*store->pixels_ss;
		status = fread(store->ss,1,read_size,fp);
		status = fread(store->ss_acrosstrack,1,read_size,fp);
		status = fread(store->ss_alongtrack,1,read_size,fp);

		/* byte swap the data if necessary */
#ifdef BYTESWAPPED
		for (i=0;i<store->beams_bath;i++)
			{
			store->bath[i] = mblgpl_swap_short(store->bath[i]);
			store->bath_acrosstrack[i] 
				= mblgpl_swap_short(store->bath_acrosstrack[i]);
			store->bath_alongtrack[i] 
				= mblgpl_swap_short(store->bath_alongtrack[i]);
			}
		for (i=0;i<store->beams_amp;i++)
			{
			store->amp[i] = mblgpl_swap_short(store->amp[i]);
			}
		for (i=0;i<store->pixels_ss;i++)
			{
			store->ss[i] = mblgpl_swap_short(store->ss[i]);
			store->ss_acrosstrack[i] 
				= mblgpl_swap_short(store->ss_acrosstrack[i]);
			store->ss_alongtrack[i] 
				= mblgpl_swap_short(store->ss_alongtrack[i]);
			}
#endif

		/* check for end of file */
		if (status == read_size) 
			{
			status = MBLGPL_SUCCESS;
			*error = MBLGPL_ERROR_NO_ERROR;
			}
		else
			{
			status = MBLGPL_FAILURE;
			*error = MBLGPL_ERROR_EOF;
			}

		/* print debug messages */
		if (verbose >= 5 && status == MBLGPL_SUCCESS)
			{
			fprintf(stderr,"\ndbg5  New data read in function <%s>\n",
				function_name);
			fprintf(stderr,"dbg5       beams_bath: %d\n",
				store->beams_bath);
			for (i=0;i<store->beams_bath;i++)
			  fprintf(stderr,"dbg5       beam:%d  flag:%d  bath:%d  acrosstrack:%d  alongtrack:%d\n",
				i,store->beamflag[i],store->bath[i],
				store->bath_acrosstrack[i],store->bath_alongtrack[i]);
			fprintf(stderr,"dbg5       beams_amp:  %d\n",
				store->beams_amp);
			for (i=0;i<store->beams_amp;i++)
			  fprintf(stderr,"dbg5       beam:%d  flag:%d  amp:%d  acrosstrack:%d  alongtrack:%d\n",
				i,store->beamflag[i],store->amp[i],
				store->bath_acrosstrack[i],store->bath_alongtrack[i]);
			fprintf(stderr,"dbg5       pixels_ss:  %d\n",
				store->pixels_ss);
			  fprintf(stderr,"dbg5       pixel:%d  ss:%d acrosstrack:%d  alongtrack:%d\n",
				i,store->ss[i],
				store->ss_acrosstrack[i],store->ss_alongtrack[i]);
			}
		}

	/* print output debug statements */
	if (verbose >= 2)
		{
		fprintf(stderr,"\ndbg2  MBLGPL function <%s> completed\n",
			function_name);
		fprintf(stderr,"dbg2  Return values:\n");
		fprintf(stderr,"dbg2       error:      %d\n",*error);
		fprintf(stderr,"dbg2  Return status:\n");
		fprintf(stderr,"dbg2       status:  %d\n",status);
		}

	/* return status */
	return(status);
}
/*--------------------------------------------------------------------*/
/*	function mblgpl_get_binary_short copies a binary short from
 *	a buffer, swapping if necessary
 */
int mblgpl_get_binary_short(int swapped, void *buffer, short *value)
{
	memcpy(value, buffer, sizeof(short));
#ifdef BYTESWAPPED
	if (swapped == MBLGPL_NO)
	    *value = mblgpl_swap_short(*value);
#else
	if (swapped == MBLGPL_YES)
	    *value = mblgpl_swap_short(*value);
#endif
	return(0);
}
/*--------------------------------------------------------------------*/
/*	function mblgpl_get_binary_int copies a binary int from
 *	a buffer, swapping if necessary
 */
int mblgpl_get_binary_int(int swapped, void *buffer, int *value)
{
	memcpy(value, buffer, sizeof(int));
#ifdef BYTESWAPPED
	if (swapped == MBLGPL_NO)
	    *value = mblgpl_swap_int(*value);
#else
	if (swapped == MBLGPL_YES)
	    *value = mblgpl_swap_int(*value);
#endif
	return(0);
}
/*--------------------------------------------------------------------*/
/*	function mblgpl_get_binary_float copies a binary float from
 *	a buffer, swapping if necessary
 */
int mblgpl_get_binary_float(int swapped, void *buffer, float *value)
{
	memcpy(value, buffer, sizeof(float));
#ifdef BYTESWAPPED
	if (swapped == MBLGPL_NO)
	    mblgpl_swap_float(value);
#else
	if (swapped == MBLGPL_YES)
	    mblgpl_swap_float(value);
#endif
	return(0);
}
/*--------------------------------------------------------------------*/
/*	function mblgpl_get_binary_double copies a binary double from
 *	a buffer, swapping if necessary
 */
int mblgpl_get_binary_double(int swapped, void *buffer, double *value)
{
	memcpy(value, buffer, sizeof(double));
#ifdef BYTESWAPPED
	if (swapped == MBLGPL_NO)
	    mblgpl_swap_double(value);
#else
	if (swapped == MBLGPL_YES)
	    mblgpl_swap_double(value);
#endif
	return(0);
}
/*--------------------------------------------------------------------*/
/*	function mblgpl_put_binary_short copies a binary short to
 *	a buffer, swapping if necessary
 */
int mblgpl_put_binary_short(int swapped, short value, void *buffer)
{
#ifdef BYTESWAPPED
	if (swapped == MBLGPL_NO)
	    value = mblgpl_swap_short(value);
#else
	if (swapped == MBLGPL_YES)
	    value = mblgpl_swap_short(value);
#endif
	memcpy(buffer, &value, sizeof(short));
	return(0);
}
/*--------------------------------------------------------------------*/
/*	function mblgpl_put_binary_int copies a binary int to
 *	a buffer, swapping if necessary
 */
int mblgpl_put_binary_int(int swapped, int value, void *buffer)
{
#ifdef BYTESWAPPED
	if (swapped == MBLGPL_NO)
	    value = mblgpl_swap_int(value);
#else
	if (swapped == MBLGPL_YES)
	    value = mblgpl_swap_int(value);
#endif
	memcpy(buffer, &value, sizeof(int));
	return(0);
}
/*--------------------------------------------------------------------*/
/*	function mblgpl_put_binary_float copies a binary float to
 *	a buffer, swapping if necessary
 */
int mblgpl_put_binary_float(int swapped, float value, void *buffer)
{
#ifdef BYTESWAPPED
	if (swapped == MBLGPL_NO)
	    mblgpl_swap_float(&value);
#else
	if (swapped == MBLGPL_YES)
	    mblgpl_swap_float(&value);
#endif
	memcpy(buffer, &value, sizeof(float));
	return(0);
}
/*--------------------------------------------------------------------*/
/*	function mblgpl_put_binary_double copies a binary double to
 *	a buffer, swapping if necessary
 */
int mblgpl_put_binary_double(int swapped, double value, void *buffer)
{
#ifdef BYTESWAPPED
	if (swapped == MBLGPL_NO)
	    mblgpl_swap_double(&value);
#else
	if (swapped == MBLGPL_YES)
	    mblgpl_swap_double(&value);
#endif
	memcpy(buffer, &value, sizeof(double));
	return(0);
}
/*--------------------------------------------------------------------*/
int mblgpl_malloc(int verbose, size_t size, void **ptr, int *error)
{
	char	*function_name = "mblgpl_malloc";
	int	status = MBLGPL_SUCCESS;

	/* print input debug statements */
	if (verbose >= 2)
		{
		fprintf(stderr,"\ndbg2  MBLGPL function <%s> called\n",
			function_name);
		fprintf(stderr,"dbg2  Input arguments:\n");
		fprintf(stderr,"dbg2       verbose:    %d\n",verbose);
		fprintf(stderr,"dbg2       size:       %d\n",size);
		fprintf(stderr,"dbg2       ptr:        %d\n",ptr);
		fprintf(stderr,"dbg2       *ptr:       %d\n",*ptr);
		}

	/* allocate memory */
	*ptr = NULL;
	if (size > 0)
		{
		if ((*ptr = (char *) malloc(size)) == NULL)
			{
			*error = MBLGPL_ERROR_MEMORY_FAIL;
			status = MBLGPL_FAILURE;
			}
		else
			{
			*error = MBLGPL_ERROR_NO_ERROR;
			status = MBLGPL_SUCCESS;
			}
		}
	else
		{
		*ptr = NULL;
		*error = MBLGPL_ERROR_NO_ERROR;
		status = MBLGPL_SUCCESS;
		}

	/* print output debug statements */
	if (verbose >= 2)
		{
		fprintf(stderr,"\ndbg2  MBLGPL function <%s> completed\n",
			function_name);
		fprintf(stderr,"dbg2  Return values:\n");
		fprintf(stderr,"dbg2       ptr:        %d\n",*ptr);
		fprintf(stderr,"dbg2       error:      %d\n",*error);
		fprintf(stderr,"dbg2  Return status:\n");
		fprintf(stderr,"dbg2       status:  %d\n",status);
		}

	/* return status */
	return(status);
}
/*--------------------------------------------------------------------*/
int mblgpl_free(int verbose, void **ptr, int *error)
{
	char	*function_name = "mblgpl_free";
	int	status = MBLGPL_SUCCESS;

	/* print input debug statements */
	if (verbose >= 2)
		{
		fprintf(stderr,"\ndbg2  MBLGPL function <%s> called\n",
			function_name);
		fprintf(stderr,"dbg2  Input arguments:\n");
		fprintf(stderr,"dbg2       verbose:    %d\n",verbose);
		fprintf(stderr,"dbg2       ptr:        %d\n",*ptr);
		}

	/* deallocate the memory if *ptr is not NULL */
	if (*ptr != NULL)
		{
		/* free the memory */
		free(*ptr);
		*ptr = NULL;
		}

	/* assume success */
	*error = MBLGPL_ERROR_NO_ERROR;
	status = MBLGPL_SUCCESS;

	/* print output debug statements */
	if (verbose >= 2)
		{
		fprintf(stderr,"\ndbg2  MBLGPL function <%s> completed\n",
			function_name);
		fprintf(stderr,"dbg2  Return value:\n");
		fprintf(stderr,"dbg2       ptr:        %d\n",*ptr);
		fprintf(stderr,"dbg2       error:      %d\n",*error);
		fprintf(stderr,"dbg2  Return status:\n");
		fprintf(stderr,"dbg2       status:     %d\n",status);
		}

	/* return status */
	return(status);
}
/*--------------------------------------------------------------------*/

