Esempio n. 1
0
status _af_iff_read_init (AFfilesetup setup, AFfilehandle file)
{
	uint32_t	type, size, formtype;
	size_t		index;
	_Track		*track;

	assert(file != NULL);
	assert(file->fh != NULL);

	af_fseek(file->fh, 0, SEEK_SET);

	af_fread(&type, 4, 1, file->fh);
	af_read_uint32_be(&size, file->fh);
	af_fread(&formtype, 4, 1, file->fh);

	if (memcmp(&type, "FORM", 4) != 0 || memcmp(&formtype, "8SVX", 4) != 0)
		return AF_FAIL;

	file->instrumentCount = 0;
	file->instruments = NULL;
	file->miscellaneousCount = 0;
	file->miscellaneous = NULL;

	/* IFF/8SVX files have only one track. */
	track = _af_track_new();
	file->trackCount = 1;
	file->tracks = track;

	/* Set the index to include the form type ('8SVX' in this case). */
	index = 4;

	while (index < size)
	{
		uint32_t	chunkid = 0, chunksize = 0;
		status		result = AF_SUCCEED;

		af_fread(&chunkid, 4, 1, file->fh);
		af_read_uint32_be(&chunksize, file->fh);

		if (!memcmp("VHDR", &chunkid, 4))
		{
			result = ParseVHDR(file, file->fh, chunkid, chunksize);
		}
		else if (!memcmp("BODY", &chunkid, 4))
		{
			result = ParseBODY(file, file->fh, chunkid, chunksize);
		}
		else if (!memcmp("NAME", &chunkid, 4) ||
			!memcmp("AUTH", &chunkid, 4) ||
			!memcmp("(c) ", &chunkid, 4) ||
			!memcmp("ANNO", &chunkid, 4))
		{
			ParseMiscellaneous(file, file->fh, chunkid, chunksize);
		}

		if (result == AF_FAIL)
			return AF_FAIL;

		/*
			Increment the index by the size of the chunk
			plus the size of the chunk header.
		*/
		index += chunksize + 8;

		/* All chunks must be aligned on an even number of bytes. */
		if ((index % 2) != 0)
			index++;

		/* Set the seek position to the beginning of the next chunk. */
		af_fseek(file->fh, index + 8, SEEK_SET);
	}

	/* The file has been successfully parsed. */
	return AF_SUCCEED;
}
Esempio n. 2
0
status _af_aiff_read_init (AFfilesetup setup, AFfilehandle file)
{
	u_int32_t	type, size, formtype;
	size_t		index = 0;
	bool		hasCOMM, hasFVER, hasSSND, hasMARK, hasINST;
	bool		hasAESD, hasNAME, hasAUTH, hasCOPY;
	_Track		*track;

	hasCOMM = AF_FALSE;
	hasFVER = AF_FALSE;
	hasSSND = AF_FALSE;
	hasMARK = AF_FALSE;
	hasINST = AF_FALSE;
	hasAESD = AF_FALSE;
	hasNAME = AF_FALSE;
	hasAUTH = AF_FALSE;
	hasCOPY = AF_FALSE;

	assert(file != NULL);
	assert(file->fh != NULL);

	af_fseek(file->fh, 0, SEEK_SET);

	af_fread(&type, 4, 1, file->fh);
	af_fread(&size, 4, 1, file->fh);
	size = BENDIAN_TO_HOST_INT32(size);
	af_fread(&formtype, 4, 1, file->fh);

	if (memcmp(&type, "FORM", 4) != 0 ||
		(memcmp(&formtype, "AIFF", 4) && memcmp(&formtype, "AIFC", 4)))
		return AF_FAIL;

#ifdef DEBUG
	printf("size: %d\n", size);
#endif

	file->instrumentCount = 0;
	file->instruments = NULL;
	file->miscellaneousCount = 0;
	file->miscellaneous = NULL;

	/* AIFF files have only one track. */
	track = _af_track_new();
	file->trackCount = 1;
	file->tracks = track;

	/* Include the offset of the form type. */
	index += 4;

	while (index < size)
	{
		u_int32_t	chunkid = 0, chunksize = 0;
		status		result = AF_SUCCEED;

#ifdef DEBUG
		printf("index: %d\n", index);
#endif
		af_fread(&chunkid, 4, 1, file->fh);
		af_fread(&chunksize, 4, 1, file->fh);
		chunksize = BENDIAN_TO_HOST_INT32(chunksize);

#ifdef DEBUG
		_af_printid(chunkid);
		printf(" size: %d\n", chunksize);
#endif

		if (!memcmp("COMM", &chunkid, 4))
		{
			hasCOMM = AF_TRUE;
			result = ParseCOMM(file, file->fh, chunkid, chunksize);
		}
		else if (!memcmp("FVER", &chunkid, 4))
		{
			hasFVER = AF_TRUE;
			ParseFVER(file, file->fh, chunkid, chunksize);
		}
		else if (!memcmp("INST", &chunkid, 4))
		{
			hasINST = AF_TRUE;
			ParseINST(file, file->fh, chunkid, chunksize);
		}
		else if (!memcmp("MARK", &chunkid, 4))
		{
			hasMARK = AF_TRUE;
			ParseMARK(file, file->fh, chunkid, chunksize);
		}
		else if (!memcmp("AESD", &chunkid, 4))
		{
			hasAESD = AF_TRUE;
			ParseAESD(file, file->fh, chunkid, chunksize);
		}
		else if (!memcmp("NAME", &chunkid, 4) ||
			!memcmp("AUTH", &chunkid, 4) ||
			!memcmp("(c) ", &chunkid, 4) ||
			!memcmp("ANNO", &chunkid, 4) ||
			!memcmp("APPL", &chunkid, 4) ||
			!memcmp("MIDI", &chunkid, 4))
		{
			ParseMiscellaneous(file, file->fh, chunkid, chunksize);
		}
		/*
			The sound data chunk is required if there are more than
			zero sample frames.
		*/
		else if (!memcmp("SSND", &chunkid, 4))
		{
			if (hasSSND)
			{
				_af_error(AF_BAD_AIFF_SSND, "AIFF file has more than one SSND chunk");
				return AF_FAIL;
			}
			hasSSND = AF_TRUE;
			result = ParseSSND(file, file->fh, chunkid, chunksize);
		}

		if (result == AF_FAIL)
			return AF_FAIL;

		index += chunksize + 8;

		/* all chunks must be aligned on an even number of bytes */
		if ((index % 2) != 0)
			index++;

		af_fseek(file->fh, index + 8, SEEK_SET);
	}

	if (!hasCOMM)
	{
		_af_error(AF_BAD_AIFF_COMM, "bad AIFF COMM chunk");
	}

	/* The file has been successfully parsed. */
	return AF_SUCCEED;
}