static char *sccsid = "@(#)icvtf.c	GIPS 2.1 (MIT/CSR) 11/14/86";

static	int	errors		= -1;		 
static	double	table[256]	= { 0.0 };	 

static
init()
{
	register i = 127;
	register double *d1 = &table[128];
	register double *d2;

	for (*(d2 = d1) = 1.0; --i > 0; d1++)
		*--d2 = 1.0/(d1[1] = 2 * *d1);
	d1[1] = *d1;
	d2[-1] = *d2;
}

static double
dconv(buf, sw)

	register unsigned char	*buf;
	register		sw;
{
	register unsigned char	*b	= buf;
	register unsigned long	fract	= 0;
	register		exp	= 4;
	register		shft;
	double			f;
	static	short		shift[]	= {-1,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0};

	while (--exp >= 0)
		fract = (fract << 8) | *b++;
	shft = shift[(fract >> 20) & 0xf];
	if (shft < 0) {
		if (fract) errors++;
		return 0;
	}
	exp = ((int)((fract >> 24) & 0177)-64)*4+128-shft;
	fract = (fract << shft) & 0xffffff;
	if (exp <= 1)
		if (exp == 1)
			fract >>= 1;
		else {
			exp = 1;
			fract = 0x800000;
			errors++;
		}
	else if (exp >= 255)
		if (exp == 255)
			fract <<= 1;
		else {
			exp = 255;
			fract = 0x7fffff;
			errors++;
		}
	f = fract * table[104];
	if (sw) {
		for (fract = 0, sw = 4; --sw >= 0; )
			fract = (fract << 8) | *b++ ;
		if (fract & 0x80000000) {
			fract &= ~0x80000000;
			f += table[104-1+shft];
		}
		f += fract * table[104-32+shft];
	}
	return f * ((*buf & 0x80) ? -table[exp] : table[exp]);
}

icvtf(fibm, nitem, farr)

	register char	*fibm;
	register int	nitem;
	register float	*farr;
{
	if (errors < 0) init();
	for (errors = 0; --nitem >= 0; fibm += 4)
		*farr++ = (float) dconv((unsigned char *)fibm, 0);
	return errors;
}

icvtd(dibm, nitem, darr)

	register char	*dibm;
	register int	nitem;
	register double	*darr;
{
	if (errors < 0) init();
	for (errors = 0; --nitem >= 0; dibm += 8)
		*darr++ = dconv((unsigned char *)dibm, 1);
	return errors;
}

icvti(iibm, nitem, iarr)

	register char	*iibm;
	register int	nitem;
	register int	*iarr;
{
	register i;
	register n;

	for ( ; --nitem >= 0; *iarr++ = n)
		for (n = 0, i = 4; --i >= 0; )
			n = (n << 8) | (*iibm++ & 0377);
	return 0;
}

icvtf_(fibm, pts, farr)

	char	*fibm;
	int	*pts;
	float  	*farr;
{
	return icvtf(fibm, *pts, farr);
}

icvtd_(dibm, pts, darr)

	char	*dibm;
	int	*pts;
	double	*darr;
{
	return icvtd(dibm, *pts, darr);
}

icvti_(iibm, pts, iarr)

	char	*iibm;
	int	*pts;
	int	*iarr;
{
	return icvti(iibm, *pts, iarr);
}
#ident "acomp: SC4.0 18 Oct 1995 C 4.0"