⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 portableio.c

📁 音频编码
💻 C
字号:
/* Copyright (C) 1988-1991 Apple Computer, Inc. * All Rights Reserved. * * Warranty Information * Even though Apple has reviewed this software, Apple makes no warranty * or representation, either express or implied, with respect to this * software, its quality, accuracy, merchantability, or fitness for a * particular purpose.  As a result, this software is provided "as is," * and you, its user, are assuming the entire risk as to its quality * and accuracy. * * This code may be used and freely distributed as long as it includes * this copyright notice and the warranty information. * * * Motorola processors (Macintosh, Sun, Sparc, MIPS, etc) * pack bytes from high to low (they are big-endian). * Use the HighLow routines to match the native format * of these machines. * * Intel-like machines (PCs, Sequent) * pack bytes from low to high (the are little-endian). * Use the LowHigh routines to match the native format * of these machines. * * These routines have been tested on the following machines: *	Apple Macintosh, MPW 3.1 C compiler *	Apple Macintosh, THINK C compiler *	Silicon Graphics IRIS, MIPS compiler *	Cray X/MP and Y/MP *	Digital Equipment VAX * * * Implemented by Malcolm Slaney and Ken Turkowski. * * Malcolm Slaney contributions during 1988-1990 include big- and little- * endian file I/O, conversion to and from Motorola's extended 80-bit * floating-point format, and conversions to and from IEEE single- * precision floating-point format. * * In 1991, Ken Turkowski implemented the conversions to and from * IEEE double-precision format, added more precision to the extended * conversions, and accommodated conversions involving +/- infinity, * NaN's, and denormalized numbers. * * $Id: portableio.c,v 1.11 2001/01/07 23:47:38 markt Exp $ */#ifdef HAVE_CONFIG_H# include <config.h>#endif#include	<stdio.h>#if defined(__riscos__) && defined(FPA10)#include	"ymath.h"#else#include	<math.h>#endif#include	"portableio.h"#ifdef WITH_DMALLOC#include <dmalloc.h>#endif/**************************************************************** * Big/little-endian independent I/O routines. ****************************************************************//* * It is a hoax to call this code portable-IO: *  *   - It doesn't work on machines with CHAR_BIT != 8 *   - it also don't test this error condition *   - otherwise it tries to handle CHAR_BIT != 8 by things like  *     masking 'putc(i&0xff,fp)' *   - It doesn't handle EOF in any way *   - it only works with ints with 32 or more bits *   - It is a collection of initial buggy code with patching the known errors *     instead of CORRECTING them!  *     For that see comments on the old Read16BitsHighLow() */#ifdef KLEMM_36signed int    ReadByte ( FILE* fp ){    int  result = getc (fp);    return result == EOF  ?  0  :  (signed char) (result & 0xFF);}unsigned int  ReadByteUnsigned ( FILE* fp ){    int  result = getc (fp);    return result == EOF  ?  0  :  (unsigned char) (result & 0xFF);}#elseintReadByte(FILE *fp){	int	result;	result = getc(fp) & 0xff;	if (result & 0x80)		result = result - 0x100;	return result;}#endif#ifdef KLEMM_36int  Read16BitsLowHigh ( FILE* fp ){    int  low  = ReadByteUnsigned (fp);    int  high = ReadByte         (fp);        return (high << 8) | low;}#elseintRead16BitsLowHigh(FILE *fp){	int	first, second, result;	first = 0xff & getc(fp);	second = 0xff & getc(fp);	result = (second << 8) + first;#ifndef	THINK_C42	if (result & 0x8000)		result = result - 0x10000;#endif	/* THINK_C */	return(result);}#endif#ifdef KLEMM_36int  Read16BitsHighLow ( FILE* fp ){    int  high = ReadByte         (fp);    int  low  = ReadByteUnsigned (fp);        return (high << 8) | low;}#elseintRead16BitsHighLow(FILE *fp){	int	first, second, result;             /* Reads the High bits, the value is -128...127 	 * (which gave after upscaling the -32768...+32512	 * Why this value is not converted to signed char?	 */        first = 0xff & getc(fp);        /* Reads the Lows bits, the value is 0...255 	 * This is correct. This value gives an additional offset	 * for the High bits	 */	second = 0xff & getc(fp);        /* This is right */	result = (first << 8) + second;            /* Now we are starting to correct the nasty bug of the first instruction	 * The value of the high bits is wrong. Always. So we must correct this	 * value. This seems to be not necessary for THINK_C42. This is either	 * a 16 bit compiler with 16 bit ints (where this bug is hidden and 0x10000	 * is not in the scope of an int) or it is not a C compiler, but only a	 * C like compiler. In the first case the '#ifndef THINK_C42' is wrong	 * because it's not a property of the THINK_C42 compiler, but of all compilers	 * with sizeof(int)*CHAR_BIT < 18.	 * Another nasty thing is that the rest of the code doesn't work for 16 bit ints,	 * so this patch don't solve the 16 bit problem.         */#ifndef	THINK_C42	if (result & 0x8000)		result = result - 0x10000;#endif	/* THINK_C */	return(result);}#endifvoidWrite8Bits(FILE *fp, int i){	putc(i&0xff,fp);}voidWrite16BitsLowHigh(FILE *fp, int i){	putc(i&0xff,fp);	putc((i>>8)&0xff,fp);}voidWrite16BitsHighLow(FILE *fp, int i){	putc((i>>8)&0xff,fp);	putc(i&0xff,fp);}#ifdef KLEMM_36int  Read24BitsHighLow ( FILE* fp ){    int  high = ReadByte         (fp);    int  med  = ReadByteUnsigned (fp);    int  low  = ReadByteUnsigned (fp);        return (high << 16) | (med << 8) | low;}#elseintRead24BitsHighLow(FILE *fp){	int	first, second, third;	int	result;	first = 0xff & getc(fp);	second = 0xff & getc(fp);	third = 0xff & getc(fp);	result = (first << 16) + (second << 8) + third;	if (result & 0x800000)		result = result - 0x1000000;	return(result);}#endif#define	Read32BitsLowHigh(f)	Read32Bits(f)#ifdef KLEMM_36int  Read32Bits ( FILE* fp ){    int  low  = ReadByteUnsigned (fp);    int  medl = ReadByteUnsigned (fp);    int  medh = ReadByteUnsigned (fp);    int  high = ReadByte         (fp);    return (high << 24) | (medh << 16) | (medl << 8) | low;}#elseintRead32Bits(FILE *fp){	int	first, second, result;	first = 0xffff & Read16BitsLowHigh(fp);	second = 0xffff & Read16BitsLowHigh(fp);	result = (second << 16) + first;#ifdef	CRAY	if (result & 0x80000000)		result = result - 0x100000000;#endif	/* CRAY */	return(result);}#endif#ifdef KLEMM_36int  Read32BitsHighLow ( FILE* fp ){    int  high = ReadByte         (fp);    int  medh = ReadByteUnsigned (fp);    int  medl = ReadByteUnsigned (fp);    int  low  = ReadByteUnsigned (fp);        return (high << 24) | (medh << 16) | (medl << 8) | low;}#elseintRead32BitsHighLow(FILE *fp){	int	first, second, result;	first = 0xffff & Read16BitsHighLow(fp);	second = 0xffff & Read16BitsHighLow(fp);	result = (first << 16) + second;#ifdef	CRAY	if (result & 0x80000000)		result = result - 0x100000000;#endif	return(result);}#endifvoidWrite32Bits(FILE *fp, int i){	Write16BitsLowHigh(fp,(int)(i&0xffffL));	Write16BitsLowHigh(fp,(int)((i>>16)&0xffffL));}voidWrite32BitsLowHigh(FILE *fp, int i){	Write16BitsLowHigh(fp,(int)(i&0xffffL));	Write16BitsLowHigh(fp,(int)((i>>16)&0xffffL));}voidWrite32BitsHighLow(FILE *fp, int i){	Write16BitsHighLow(fp,(int)((i>>16)&0xffffL));	Write16BitsHighLow(fp,(int)(i&0xffffL));}#ifdef KLEMM_36void ReadBytes (FILE     *fp, char *p, int n) {    memset ( p, 0, n );    fread  ( p, 1, n, fp );}#elsevoid ReadBytes(FILE	*fp, char *p, int n){	/* What about fread? */	 	while (!feof(fp) & (n-- > 0))		*p++ = getc(fp);}#endifvoid ReadBytesSwapped(FILE *fp, char *p, int n){	register char	*q = p;	/* What about fread? */	  	while (!feof(fp) & (n-- > 0))		*q++ = getc(fp);        /* If not all bytes could be read, the resorting is different	 * from the normal resorting. Is this intention or another bug?	 */	for (q--; p < q; p++, q--){		n = *p;		*p = *q;		*q = n;	}}#ifdef KLEMM_36void WriteBytes(FILE *fp, char *p, int n){    /* return n == */    fwrite ( p, 1, n, fp );}#elsevoid WriteBytes(FILE *fp, char *p, int n){        /* No error condition checking */        while (n-- > 0)		putc(*p++, fp);}#endif#ifdef KLEMM_36void WriteBytesSwapped(FILE *fp, char *p, int n){    p += n;    while ( n-- > 0 )	putc ( *--p, fp );}#elsevoid WriteBytesSwapped(FILE *fp, char *p, int n){	p += n-1;	while (n-- > 0)		putc(*p--, fp);}#endif/**************************************************************** * The following two routines make up for deficiencies in many * compilers to convert properly between unsigned integers and * floating-point.  Some compilers which have this bug are the * THINK_C compiler for the Macintosh and the C compiler for the * Silicon Graphics MIPS-based Iris. ****************************************************************/#ifdef applec	/* The Apple C compiler works */# define FloatToUnsigned(f)	((unsigned long)(f))# define UnsignedToFloat(u)	((double)(u))#else /* applec */# define FloatToUnsigned(f)	((unsigned long)(((long)((f) - 2147483648.0)) + 2147483647L + 1))# define UnsignedToFloat(u)	(((double)((long)((u) - 2147483647L - 1))) + 2147483648.0)#endif /* applec *//**************************************************************** * Extended precision IEEE floating-point conversion routines ****************************************************************/doubleConvertFromIeeeExtended(char* bytes){	double	f;	long	expon;	unsigned long hiMant, loMant;#ifdef	TESTprintf("ConvertFromIEEEExtended(%lx,%lx,%lx,%lx,%lx,%lx,%lx,%lx,%lx,%lx\r",	(long)bytes[0], (long)bytes[1], (long)bytes[2], (long)bytes[3],	(long)bytes[4], (long)bytes[5], (long)bytes[6],	(long)bytes[7], (long)bytes[8], (long)bytes[9]);#endif	expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);	hiMant	=	((unsigned long)(bytes[2] & 0xFF) << 24)			|	((unsigned long)(bytes[3] & 0xFF) << 16)			|	((unsigned long)(bytes[4] & 0xFF) << 8)			|	((unsigned long)(bytes[5] & 0xFF));	loMant	=	((unsigned long)(bytes[6] & 0xFF) << 24)			|	((unsigned long)(bytes[7] & 0xFF) << 16)			|	((unsigned long)(bytes[8] & 0xFF) << 8)			|	((unsigned long)(bytes[9] & 0xFF));        /* This case should also be called if the number is below the smallest	 * positive double variable */	if (expon == 0 && hiMant == 0 && loMant == 0) {		f = 0;	}	else {	        /* This case should also be called if the number is too large to fit into 		 * a double variable */	    		if (expon == 0x7FFF) {	/* Infinity or NaN */			f = HUGE_VAL;		}		else {			expon -= 16383;			f  = ldexp(UnsignedToFloat(hiMant), (int) (expon -= 31));			f += ldexp(UnsignedToFloat(loMant), (int) (expon -= 32));		}	}	if (bytes[0] & 0x80)		return -f;	else		return f;}doubleReadIeeeExtendedHighLow(FILE *fp){	char	bytes [10];	ReadBytes ( fp, bytes, 10 );	return ConvertFromIeeeExtended ( bytes );}

⌨️ 快捷键说明

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