esig_edr.c

来自「speech signal process tools」· C语言 代码 · 共 2,690 行 · 第 1/4 页

C
2,690
字号
	return NULL;		/* Inconsistent rank and dimensions. */    if (EdrReadLong(field->dim, rank, file, longlong) != rank)	return NULL;	/* Couldn't get dimensions. */    /* Read units, scale, offset, axis_names. */    if (!ReadEdrString(&field->units, file, longlong))	return NULL;    if (EdrReadDouble(&field->scale, 1, file) != 1)	return NULL;		/* Couldn't get scale. */    if (EdrReadDouble(&field->offset, 1, file) != 1)	return NULL;		/* Couldn't get offset. */    if (EdrReadLong(&num_ax_names, 1, file, longlong) != 1)	return NULL;		/* Couldn't get number of axis names. */    if (num_ax_names > rank)	return NULL;		/* Bad value for num_ax_names. */    if (num_ax_names != 0)    {	field->axis_names = (char **) malloc(rank * sizeof(char *));	if (field->axis_names == NULL)	    return NULL;	/* Allocation failure. */	for (i = 0; i < num_ax_names; i++)	    ReadEdrString(&field->axis_names[i], file, longlong);	for ( ; i < rank; i++)	    field->axis_names[i] = NULL;    }    /* Read occurrence class. */    if (EdrReadShort(&field->occurrence, 1, file) != 1)	return NULL;		/* Couldn't get occurrence code. */    /* Read data if required. */    if (type != NO_TYPE	&& field->occurrence != REQUIRED && field->occurrence != OPTIONAL)    {	if (!ReadEdrData(field, file, longlong))	    return NULL;	/* Failure reading data. */    }    /* Read subfield list. */    if (!ReadEdrFieldList(&field->subfields, file, longlong))    {	FreeFieldSpec(field);	return NULL;		/* Failure getting subfields. */    }    return field;		/* Success. */}/* * Read character string in EDR format from file and output * pointer to it.  Return TRUE on success, FALSE on failure. */static intReadEdrString(char  **string,	      FILE  *file,	      int   longlong){    long    length;    char    *str;    long    i;    int     ch;    if (EdrReadLong(&length, 1, file, longlong) != 1)	return FALSE;		/* Couldn't get length. */    str = (char *) malloc(length + 1);    if (str ==  NULL)	return FALSE;    for (i = 0; i < length && (ch = getc(file)) != EOF; i++)	str[i] = ch;    if (i < length)    {	free(str);	return FALSE;    }    str[length] = '\0';    if (string != NULL)	*string = str;    return TRUE;}/* * Read items of data from a file into a block of storage indicated * by a pointer "data".  The number of items is given by "length", * and their data type is indicated by the integer code "type". * Return the number of successfully read items.  (A value other * than "length" indicates an error). */static intEdrRead(void	*data,	int	type,	long	length,	FILE	*file,	int	longlong){    if (file == NULL || data == NULL || length <= 0)	return 0;    switch (type)    {    case ARRAY:	return EdrReadArray((Array *) data, length, file, longlong);    case DOUBLE:	return EdrReadDouble((double *) data, length, file);    case FLOAT:	return EdrReadFloat((float *) data, length, file);    case LONG:	return EdrReadLong((long *) data, length, file, longlong);    case ULONG:	return EdrReadUlong((Ulong *) data, length, file, longlong);    case SHORT:	return EdrReadShort((short *) data, length, file);    case USHORT:	return EdrReadUshort((Ushort *) data, length, file);    case SCHAR:	return EdrReadSchar((Schar *) data, length, file);    case UCHAR:	return EdrReadUchar((Uchar *) data, length, file);    case BOOL:	return EdrReadBool((Bool *) data, length, file);    case DOUBLE_COMPLEX:	return EdrReadDoubleComplex((DoubleComplex *) data, length, file);    case FLOAT_COMPLEX:	return EdrReadFloatComplex((FloatComplex *) data, length, file);    case LONG_COMPLEX:	return EdrReadLongComplex((LongComplex *) data,				  length, file, longlong);    case SHORT_COMPLEX:	return EdrReadShortComplex((ShortComplex *) data, length, file);    case SCHAR_COMPLEX:	return EdrReadScharComplex((ScharComplex *) data, length, file);    case CHAR:	return EdrReadChar((char *) data, length, file);    case WCHAR:	return EdrReadWchar((Wchar *) data, length, file);    default:    /* Invalid code or NO_TYPE. */	return 0;    }}/* * Read from file the EDR1 or EDR2 representation of one item of type * ARRAY.  Store the type, rank, dimensions, and data in the members of * the array structure, allocating the necessary space for dimensions * and data.  Return TRUE for success, FALSE for failure. */static intReadEdrArray(Array  *array,	     FILE   *file,	     int    longlong){    short	type;		/* data type code */    short	rank;		/* number of dimensions */    long	*dim;		/* dimensions */    void	*data;    long	length;    long	size;    if (array == NULL || file == NULL)	return FALSE;    if (EdrReadShort(&type, 1, file)  != 1)	return FALSE;		/* Couldn't get type. */    if (EdrReadShort(&rank, 1, file) != 1)	return FALSE;		/* Couldn't get rank. */    if (rank == 0)	dim = NULL;    else    {	dim = (long *) malloc(rank * sizeof(long));	if (dim == NULL)	    return FALSE;	if (EdrReadLong(dim, rank, file, longlong) != rank)	{	    free(dim);	    return FALSE;	}    }    length = LongProd(rank, dim);    size = InternTypeSize(type);    if (length == 0)	data = NULL;    else    {	data = malloc(length*size);	if (data == NULL	    || EdrRead(data, type, length, file, longlong) != length)	{	    if (dim != NULL)		free(dim);	    return FALSE;	}    }    array->type = type;    array->rank = rank;    array->dim = dim;    array->data = data;    return TRUE;}/* * Each of the following functions with names of the form * *      EdrRead<type> * * takes three arguments: *	<type>	*data, *	long	length, *	FILE	*file, * and in some cases a fourth: *	int	longlong * The function reads "length" items of data of the indicated data type * in EDR portable binary format from the stream "file" into a block of * storage indicated by "data".  The fourth argument, "longlong", is * present when the EDR1 and EDR2 representations of the data type differ; * a value of 1 indicates EDR1, and 2 indicates EDR2.  The int return * value is the number of items successfully read, which will be less * than "length" in case of error. *//* Read items of type ARRAY */static intEdrReadArray(Array	*data,	     long	length,	     FILE	*file,	     int	longlong){    long	n;    for (n = 0;	 n < length && ReadEdrArray(&data[n], file, longlong);	 n++)    { }    return n;}/* Read items of type DOUBLE */static intEdrReadDouble(double	*data,	      long	length,	      FILE	*file){    long	    n;		/* number of items read */    unsigned long   hi;		/* 28 high_order fraction bits				   (and hidden bit) */    unsigned long   lo;		/* 24 low_order fraction bits  */    int		    ex;		/* exponent */    int		    sn;		/* sign */    int		    ch;		/* input character */    double	    item;	/* one input data item */    for (n = 0; n < length; n++)    {	if ((ch = getc(file)) == EOF)	    break;	sn = ((ch & 0x80) != 0); /* sign */	ex = ch & 0x7f;		/* 7 bits of exponent */	if ((ch = getc(file)) == EOF)	    break;	ex = (ex << 4) | (ch >> 4); /* rest of exponent */	hi = ch & 0x0f;		/* first 4 fraction bits */	if ((ch = getc(file)) == EOF)	    break;	hi = (hi << 8) | ch;	if ((ch = getc(file)) == EOF)	    break;	hi = (hi << 8) | ch;	if ((ch = getc(file)) == EOF)	    break;	hi = (hi << 8) | ch;	if ((ch = getc(file)) == EOF)	    break;	lo = ch;		/* start on low-order 24 bits */	if ((ch = getc(file)) == EOF)	    break;	lo = (lo << 8) | ch;	if ((ch = getc(file)) == EOF)	    break;	lo = (lo << 8) | ch;	if (ex == 2047)		/* Inf or NaN */	    item = HUGE_VAL;	else	{	    if (ex == 0)	/* unnormalized */		ex = 1;		/* adjust for different exponent bias */	    else		/* normalized */		hi |= 0x10000000; /* hidden bit */	    item = ldexp((double) hi, 24) + (double) lo;	    /* fraction bits as integer, i.e. scaled by 2^52 */	    item = ldexp(item, ex - 1075);	    /* 1075: number of fractional places (52)	       minus exponent bias (-1023) */	}	data[n] = (sn) ? -item : item;    }    return n;}/* Read items of type FLOAT */static intEdrReadFloat(float  *data,	     long   length,	     FILE   *file){    long	    n;		/* number of items read */    unsigned long   fr;		/* 23 fraction bits (and hidden bit) */    int		    ex;		/* exponent */    int		    sn;		/* sign */    int		    ch;		/* input character */    double	    item;	/* one input data item */    for (n = 0; n < length; n++)    {	if ((ch = getc(file)) == EOF)	    break;	sn = ((ch & 0x80) != 0); /* sign */	ex = ch & 0x7f;		/* 7 bits of exponent */	if ((ch = getc(file)) == EOF)	    break;	ex = (ex << 1) | (ch >> 7); /* rest of exponent */	fr = ch & 0x7f;		/* first 7 fraction bits */	if ((ch = getc(file)) == EOF)	    break;	fr = (fr << 8) | ch;	if ((ch = getc(file)) == EOF)	    break;	fr = (fr << 8) | ch;	if (ex == 255)		/* Inf or NaN */	    item = FLT_MAX;	/*! What's a portable way to get the float equivalent of HUGE_VAL	 * in ANSI C? */	else	{	    if (ex == 0)	/* unnormalized */		ex = 1;		/* adjust for different exponent bias */	    else		/* normalized */		fr |= 0x800000;	/* hidden bit */	    item = ldexp((double) fr, ex - 150);	    /* 150: number of fractional places (23)	       minus exponent bias (-127) */	    if (item > FLT_MAX)		item = FLT_MAX;	}	data[n] = (sn) ? -item : item;    }    return n;}/* Read items of type LONG */static intEdrReadLong(long    *data,	    long    length,	    FILE    *file,	    int     longlong){    long	    n;		/* number of items read */    int		    ch;		/* input character */    switch (longlong)    {    case EDR1:	{	    unsigned long		item;	/* one input data item */	    for (n = 0; n < length; n++)	    {		if ((ch = getc(file)) == EOF)		    break;		item = ch;		if ((ch = getc(file)) == EOF)		    break;		item = (item << 8) | ch;		if ((ch = getc(file)) == EOF)		    break;		item = (item << 8) | ch;		if ((ch = getc(file)) == EOF)		    break;		item = (item << 8) | ch;		if ((item & 0x80000000) == 0)		    data[n] = item;#if (LONG_MIN == -0xffffffff)	/* Unlikely on 2's-complement machine,				 * but allowed by ANSI. */		else		    if (item == 0x80000000)		    {			data[n] = LONG_MIN;			/* CLIPPING */		    }#endif		else		    data[n] = -1L - (long) (item ^ 0xffffffff);	    }	    return n;	}	break;    case EDR2:	{	    unsigned long		hi, lo;	    for (n = 0; n < length; n++)	    {		/* Get high-order 4 bytes */		if ((ch = getc(file)) == EOF)		    break;		hi = ch;		if ((ch = getc(file)) == EOF)		    break;		hi = (hi << 8) | ch;		if ((ch = getc(file)) == EOF)		    break;		hi = (hi << 8) | ch;		if ((ch = getc(file)) == EOF)		    break;		hi = (hi << 8) | ch;		/* Get low-order 4 bytes */		if ((ch = getc(file)) == EOF)		    break;		lo = ch;		if ((ch = getc(file)) == EOF)		    break;		lo = (lo << 8) | ch;		if ((ch = getc(file)) == EOF)		    break;		lo = (lo << 8) | ch;		if ((ch = getc(file)) == EOF)		    break;		lo = (lo << 8) | ch;		/* Combine the pieces */#if (ULONG_MAX > 0xffffffffUL)	/* unsigned longs more than 32 bits */		{		    const unsigned long			lmaxhi = LONG_MAX >> 32,			lmaxlo = LONG_MAX & 0xffffffffUL,			lminhi = ~ (~ (unsigned long) LONG_MIN >> 32),			lminlo = LONG_MIN & 0xffffffffUL,			sgnext = ~ 0xffffffffUL;		    if ((hi & 0x80000000) == 0)	/* non-negative */		    {			if (hi > lmaxhi || hi == lmaxhi && lo > lmaxlo)			{			    data[n] = LONG_MAX;			    /* CLIPPING */			}			else			    data[n] = (hi << 32) | lo;		    }		    else	/* negative */		    {			hi |= sgnext;			if (hi < lminhi || hi == lminhi && lo < lminlo)			{			    data[n] = LONG_MIN;			    /* CLIPPING */			}			else			    data[n] = -1L - (long) ~((hi << 32) | lo);		    }		}#else  /* 32-bit unsigned longs */		{		    if ((hi & 0x80000000) == 0)	/* non-negative */		    {			if (hi != 0 || lo > LONG_MAX)			{			    data[n] = LONG_MAX;			    /* CLIPPING */			}			else			    data[n] = lo;		    }		    else	/* negative */		    {			if (hi != -1UL || lo < LONG_MIN)			{			    data[n] = LONG_MIN;			    /* CLIPPING */			}			else			    data[n] = -1L - (long) (0xffffffff ^ lo);		    }		}#endif	    }	    return n;	}	break;    default:	return 0;    }}/* Read items of type ULONG */static intEdrReadUlong(Ulong *data,	     long length,	     FILE *file,	     int longlong){    long	    n;		/* number of items read */    int		    ch;		/* input character */    switch (longlong)    {    case EDR1:	{	    unsigned long		item;	/* one input data item */	    for (n = 0; n < length; n++)	    {		if ((ch = getc(file)) == EOF)		    break;		item = ch;		if ((ch = getc(file)) == EOF)		    break;		item = (item << 8) | ch;		if ((ch = getc(file)) == EOF)		    break;		item = (item << 8) | ch;		if ((ch = getc(file)) == EOF)		    break;		item = (item << 8) | ch;		data[n] = item;	    }	    return n;	}	break;    case EDR2:	{	    unsigned long		hi, lo;	    for (n = 0; n < length; n++)	    {		/* Get high-order 4 bytes */		if ((ch = getc(file)) == EOF)		    break;		hi = ch;		if ((ch = getc(file)) == EOF)		    break;		hi = (hi << 8) | ch;		if ((ch = getc(file)) == EOF)		    break;		hi = (hi << 8) | ch;		if ((ch = getc(file)) == EOF)		    break;		hi = (hi << 8) | ch;		/* Get low-order 4 bytes */		if ((ch = getc(file)) == EOF)		    break;		lo = ch;		if ((ch = getc(file)) == EOF)		    break;		lo = (lo << 8) | ch;		if ((ch = getc(file)) == EOF)		    break;		lo = (lo << 8) | ch;		if ((ch = getc(file)) == EOF)		    break;		lo = (lo << 8) | ch;		/* Combine the pieces */#if (ULONG_MAX > 0xffffffffUL)	/* unsigned longs more than 32 bits */		{		    const unsigned long			ulmaxhi = ULONG_MAX >> 32,			ulmaxlo = ULONG_MAX & 0xffffffffUL;		    if (hi > ulmaxhi || hi == ulmaxhi && lo > ulmaxlo)		    {			data[n] = ULONG_MAX;			/* CLIPPING */		    }		    else			data[n] = (hi << 32) | lo;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?