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

📄 filehdr.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#ifndef lintstatic	char sccsid[] = "@(#)filehdr.c 1.1 92/07/30 Copyr 1989 Sun Micro";#endif/* Copyright (c) 1989 by Sun Microsystems, Inc. *//* * This file contains a set of Very Paranoid routines to convert * audio file headers to in-core audio headers and vice versa. * * They are robust enough to handle any random file input without * crashing miserably.  Of course, bad audio headers coming from * the calling program can cause significant problems. */#include "libaudio_impl.h"#include "audio_errno.h"#include "audio_hdr.h"#include "audio_filehdr.h"#include <fcntl.h>#include <sys/types.h>#include <sys/file.h>#include <sys/stat.h>/* Round up to a double boundary */#define	ROUND_DBL(x)	(((x) + 7) & ~7)/* * Write an audio file header to an output stream. * * The file header is encoded from the supplied Audio_hdr structure. * If 'infop' is not NULL, it is the address of a buffer containing 'info' * data.  'ilen' specifies the size of this buffer. * The entire file header will be zero-padded to a double-word boundary. * * Note that the file header is stored on-disk in big-endian format, * regardless of the machine type. * * Note also that the output file descriptor must not have been set up * non-blocking i/o.  If non-blocking behavior is desired, set this * flag after writing the file header. */intaudio_write_filehdr(fd, hdrp, infop, ilen)	int		fd;		/* file descriptor */	Audio_hdr	*hdrp;		/* audio header */	char		*infop;		/* info buffer pointer */	unsigned	ilen;		/* buffer size */{	int		err;	int		hdrsize;	Audio_filehdr	fhdr;		/* temporary file header storage */	unsigned char	*buf;		/* temporary buffer */	unsigned char	*bp;	fhdr.magic = AUDIO_FILE_MAGIC;	/* set the magic number */	/*	 * Set the size of the real header (hdr size + info size).	 * If no supplied info, make sure a minimum size is accounted for.	 * Also, round the whole thing up to double-word alignment.	 */	if ((infop == NULL) || (ilen == 0)) {		infop = NULL;		ilen = 4;	}	hdrsize = sizeof (Audio_filehdr) + ilen;	fhdr.hdr_size = ROUND_DBL(hdrsize);	/* Decode the audio header structure. */	fhdr.data_size = hdrp->data_size;	fhdr.sample_rate = hdrp->sample_rate;	fhdr.channels = hdrp->channels;	/* Check the data encoding. */	switch (hdrp->encoding) {	case AUDIO_ENCODING_ULAW:		if (hdrp->samples_per_unit != 1)			return (AUDIO_ERR_BADHDR);		switch (hdrp->bytes_per_unit) {		case 1:			fhdr.encoding = AUDIO_FILE_ENCODING_MULAW_8; break;		default:			return (AUDIO_ERR_BADHDR);		}		break;	case AUDIO_ENCODING_LINEAR:		if (hdrp->samples_per_unit != 1)			return (AUDIO_ERR_BADHDR);		switch (hdrp->bytes_per_unit) {		case 1:			fhdr.encoding = AUDIO_FILE_ENCODING_LINEAR_8; break;		case 2:			fhdr.encoding = AUDIO_FILE_ENCODING_LINEAR_16; break;		case 3:			fhdr.encoding = AUDIO_FILE_ENCODING_LINEAR_24; break;		case 4:			fhdr.encoding = AUDIO_FILE_ENCODING_LINEAR_32; break;		default:			return (AUDIO_ERR_BADHDR);		}		break;	case AUDIO_ENCODING_FLOAT:		if (hdrp->samples_per_unit != 1)			return (AUDIO_ERR_BADHDR);		switch (hdrp->bytes_per_unit) {		case 4:			fhdr.encoding = AUDIO_FILE_ENCODING_FLOAT; break;		case 8:			fhdr.encoding = AUDIO_FILE_ENCODING_DOUBLE; break;		}		break;	default:		return (AUDIO_ERR_BADHDR);	}	/* Allocate a buffer to hold the data */	buf = (unsigned char *)malloc((unsigned)fhdr.hdr_size);	if (buf == NULL)		return (AUDIO_UNIXERROR);	bp = buf;#ifndef lint	/* Encode the 32-bit integer header fields. */	ENCODE_LONG(&fhdr.magic, buf); buf += 4;	ENCODE_LONG(&fhdr.hdr_size, buf); buf += 4;	ENCODE_LONG(&fhdr.data_size, buf); buf += 4;	ENCODE_LONG(&fhdr.encoding, buf); buf += 4;	ENCODE_LONG(&fhdr.sample_rate, buf); buf += 4;	ENCODE_LONG(&fhdr.channels, buf); buf += 4;#endif	/* Copy the info data */	if (infop != NULL) {		bcopy(infop, (char *)buf, (int)ilen);		buf += ilen;	}	if (fhdr.hdr_size > hdrsize)		bzero((char *)buf, (int)(fhdr.hdr_size - hdrsize));	/* Write and free the holding buffer */	err = write(fd, (char *)bp, (int)fhdr.hdr_size);	(void) free((char *)bp);	if (err != fhdr.hdr_size)		return ((err < 0) ? AUDIO_UNIXERROR : AUDIO_ERR_BADFILEHDR);	return (AUDIO_SUCCESS);}/* * Rewrite the data size field of an audio header to the output stream. * * If the output file is capable of seeking, rewrite the audio file header * data_size field with the supplied value. * Otherwise, return AUDIO_ERR_NOEFFECT. */intaudio_rewrite_filesize(fd, size)	int		fd;		/* file descriptor */	unsigned	size;		/* new data size */{	int		err;	unsigned char	*buf;	Audio_filehdr	fhdr;	/* Can we seek back in this file and write without appending? */	err = (char *)&fhdr.data_size - (char *)&fhdr;	if ((lseek(fd, (off_t)err, L_SET) < 0) ||	    (fcntl(fd, F_GETFL, 0) & FAPPEND))		return (AUDIO_ERR_NOEFFECT);	/* Allocate a buffer to hold the data */	buf = (unsigned char *)malloc(sizeof (fhdr.data_size));	if (buf == NULL)		return (AUDIO_UNIXERROR);#ifndef lint	/* Encode the 32-bit integer header field */	ENCODE_LONG(&size, buf);#else	size = size;#endif	/* Write and free the holding buffer */	err = write(fd, (char *)buf, sizeof (fhdr.data_size));	(void) free((char *)buf);	if (err != sizeof (fhdr.data_size))		return ((err < 0) ? AUDIO_UNIXERROR : AUDIO_ERR_BADFILEHDR);	return (AUDIO_SUCCESS);}/* * Decode an audio file header from an input stream. * * The file header is decoded into the supplied Audio_hdr structure. * If 'infop' is not NULL, it is the address of a buffer to which the * 'info' portion of the file header will be copied.  'ilen' specifies * the maximum number of bytes to copy.  The buffer will be NULL-terminated, * even if it means over-writing the last byte. * * Note that the file header is stored on-disk in big-endian format, * regardless of the machine type.  This may not have been true if * the file was written on a non-Sun machine.  For now, such * files will appear invalid. * * Note also that the input file descriptor must not have been set up * non-blocking i/o.  If non-blocking behavior is desired, set this * flag after reading the file header. */intaudio_read_filehdr(fd, hdrp, infop, ilen)	int		fd;		/* input file descriptor */	Audio_hdr	*hdrp;		/* output audio header */	char		*infop;		/* info buffer pointer */	unsigned	ilen;		/* buffer size */{	int		err;	unsigned	isize;	unsigned	resid;	unsigned char	buf[sizeof (Audio_filehdr)];	struct stat	st;	/* Read the header (but not the text info). */	err = read(fd, (char *)buf, sizeof (buf));	if ((err != sizeof (buf)) ||	    (audio_decode_filehdr(buf, hdrp, &isize) != AUDIO_SUCCESS)) {		goto checkerror;	}	/* Stat the file, to determine if it is a regular file. */	err = fstat(fd, &st);	if (err < 0)		return (AUDIO_UNIXERROR);	/*	 * If data_size is not indeterminate (i.e., this isn't a pipe),	 * try to validate the hdr_size and data_size.	 */	if (hdrp->data_size != AUDIO_UNKNOWN_SIZE) {		/* Only trust the size for regular files */		if (S_ISREG(st.st_mode)) {			if (st.st_size !=			    (isize + hdrp->data_size + sizeof (Audio_filehdr)))				return (AUDIO_ERR_BADFILEHDR);		}	}	/*	 * If infop is non-NULL, try to read in the info data.	 */	resid = isize;	if ((infop != NULL) && (ilen != 0)) {		if (isize > ilen)			isize = ilen;		err = read(fd, infop, (int)isize);		if (err != isize)			goto checkerror;		/* Zero any residual bytes in the text buffer */		if (isize < ilen)			bzero(&infop[isize], (int)(ilen - isize));		else			infop[ilen - 1] = '\0';	/* zero-terminate */		resid -= err;			/* subtract the amount read */	}	/*	 * If we truncated the info, seek or read data until info size is	 * satisfied.  If regular file, seek nearly to end and check for eof.	 */	if (resid != 0) {		if (S_ISREG(st.st_mode)) {			err = lseek(fd, (off_t)(resid - 1), L_INCR);			if ((err < 0) ||			    ((err = read(fd, (char *)buf, 1)) != 1))				goto checkerror;		} else while (resid != 0) {			char	junk[8192];	/* temporary buffer */			isize = (resid > sizeof (junk)) ? sizeof (junk) : resid;			err = read(fd, junk, (int)isize);			if (err != isize)				goto checkerror;			resid -= err;		}	}	return (AUDIO_SUCCESS);checkerror:	return ((err < 0) ? AUDIO_UNIXERROR : AUDIO_ERR_BADFILEHDR);}/* * Return TRUE if the named file is an audio file.  Else, return FALSE. */intaudio_isaudiofile(name)	char		*name;{	int		fd;	int		err;	Audio_hdr	hdr;	unsigned char	buf[sizeof (Audio_filehdr)];	unsigned	isize;	/* Open the file (set O_NDELAY in case the name refers to a device) */	fd = open(name, O_RDONLY | O_NDELAY);	if (fd < 0)		return (FALSE);	/* Read the header (but not the text info). */	err = read(fd, (char *)buf, sizeof (buf));	(void) close(fd);	return ((err == sizeof (buf)) &&	    (audio_decode_filehdr(buf, &hdr, &isize) == AUDIO_SUCCESS));}/* * Try to decode buffer containing an audio file header into an audio header. */intaudio_decode_filehdr(buf, hdrp, isize)	unsigned char	*buf;		/* buffer address */	Audio_hdr	*hdrp;		/* output audio header */	unsigned	*isize;		/* output size of info */{	Audio_filehdr	fhdr;		/* temporary file header storage */#ifndef lint	/* Decode the 32-bit integer header fields. */	DECODE_LONG(buf, &fhdr.magic); buf += 4;	DECODE_LONG(buf, &fhdr.hdr_size); buf += 4;	DECODE_LONG(buf, &fhdr.data_size); buf += 4;	DECODE_LONG(buf, &fhdr.encoding); buf += 4;	DECODE_LONG(buf, &fhdr.sample_rate); buf += 4;	DECODE_LONG(buf, &fhdr.channels);#else	buf = buf;#endif	/* Check the magic number. */	if (fhdr.magic != AUDIO_FILE_MAGIC)		return (AUDIO_ERR_BADFILEHDR);	/* Decode into the audio header structure. */	hdrp->data_size = fhdr.data_size;	hdrp->sample_rate = fhdr.sample_rate;	hdrp->channels = fhdr.channels;	/* Set the info field size (ie, number of bytes left before data). */	*isize = fhdr.hdr_size - sizeof (Audio_filehdr);	/* Check the data encoding. */	switch (fhdr.encoding) {	case AUDIO_FILE_ENCODING_MULAW_8:		hdrp->encoding = AUDIO_ENCODING_ULAW;		hdrp->bytes_per_unit = 1;		hdrp->samples_per_unit = 1;		break;	case AUDIO_FILE_ENCODING_LINEAR_8:		hdrp->encoding = AUDIO_ENCODING_LINEAR;		hdrp->bytes_per_unit = 1;		hdrp->samples_per_unit = 1;		break;	case AUDIO_FILE_ENCODING_LINEAR_16:		hdrp->encoding = AUDIO_ENCODING_LINEAR;		hdrp->bytes_per_unit = 2;		hdrp->samples_per_unit = 1;		break;	case AUDIO_FILE_ENCODING_LINEAR_24:		hdrp->encoding = AUDIO_ENCODING_LINEAR;		hdrp->bytes_per_unit = 3;		hdrp->samples_per_unit = 1;		break;	case AUDIO_FILE_ENCODING_LINEAR_32:		hdrp->encoding = AUDIO_ENCODING_LINEAR;		hdrp->bytes_per_unit = 4;		hdrp->samples_per_unit = 1;		break;	case AUDIO_FILE_ENCODING_FLOAT:		hdrp->encoding = AUDIO_ENCODING_FLOAT;		hdrp->bytes_per_unit = 4;		hdrp->samples_per_unit = 1;		break;	case AUDIO_FILE_ENCODING_DOUBLE:		hdrp->encoding = AUDIO_ENCODING_FLOAT;		hdrp->bytes_per_unit = 8;		hdrp->samples_per_unit = 1;		break;	default:		return (AUDIO_ERR_BADFILEHDR);	}	return (AUDIO_SUCCESS);}

⌨️ 快捷键说明

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