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 + -
显示快捷键?