Example #1
0
guid_type_t ASFParser::asf_guid_get_type(const asf_guid_t *guid)
{
        guid_type_t ret;

        ret = asf_guid_get_object_type(guid);
        if (ret == GUID_UNKNOWN) {
                ret = asf_guid_get_stream_type(guid);
        }

        return ret;
}
Example #2
0
/**
 * Reads the stream properties object's data into the equivalent
 * data structure, and stores it in asf_stream_t structure
 * with the equivalent stream type. Needs the stream properties
 * object data as its input.
 */
static int
asf_parse_header_stream_properties(asf_stream_t *stream,
                                   uint8_t *objdata,
                                   uint32_t objsize)
{
	asf_guid_t guid;
	guid_type_t type;
	uint32_t datalen;
	uint8_t *data;

	if (objsize < 78) {
		return ASF_ERROR_INVALID_LENGTH;
	}

	asf_byteio_getGUID(&guid, objdata);
	type = asf_guid_get_stream_type(&guid);

	datalen = asf_byteio_getDWLE(objdata + 40);
	if (datalen > objsize - 78) {
		return ASF_ERROR_INVALID_LENGTH;
	}
	data = objdata + 54;

	if (type == GUID_STREAM_TYPE_EXTENDED) {
		/* FIXME: Need to find out what actually is here...
		          but for now we can just skip the extended part */
		if (datalen < 64)
			return ASF_ERROR_INVALID_LENGTH;

		data += 64;
		datalen -= 64;

		/* update the stream type with correct one */
		asf_byteio_getGUID(&guid, objdata);
		type = asf_guid_get_stream_type(&guid);
	}

	switch (type) {
	case GUID_STREAM_TYPE_AUDIO:
	case GUID_STREAM_TYPE_EXTENDED_AUDIO:
	{
		asf_waveformatex_t *wfx;

		stream->type = ASF_STREAM_TYPE_AUDIO;

		if (datalen < 18) {
			return ASF_ERROR_INVALID_LENGTH;
		}
		if (asf_byteio_getWLE(data + 16) > datalen - 16) {
			return ASF_ERROR_INVALID_LENGTH;
		}

		/* this should be freed in asf_close function */
		stream->properties = malloc(sizeof(asf_waveformatex_t));
		if (!stream->properties)
			return ASF_ERROR_OUTOFMEM;
		stream->flags |= ASF_STREAM_FLAG_AVAILABLE;

		wfx = stream->properties;
		wfx->wFormatTag = asf_byteio_getWLE(data);
		wfx->nChannels = asf_byteio_getWLE(data + 2);
		wfx->nSamplesPerSec = asf_byteio_getDWLE(data + 4);
		wfx->nAvgBytesPerSec = asf_byteio_getDWLE(data + 8);
		wfx->nBlockAlign = asf_byteio_getWLE(data + 12);
		wfx->wBitsPerSample = asf_byteio_getWLE(data + 14);
		wfx->cbSize = asf_byteio_getWLE(data + 16);
		wfx->data = data + 18;

		if (wfx->cbSize > datalen - 18) {
			debug_printf("Invalid waveformatex data length, truncating!");
			wfx->cbSize = datalen - 18;
		}

		break;
	}
	case GUID_STREAM_TYPE_VIDEO:
	{
		asf_bitmapinfoheader_t *bmih;
		uint32_t width, height, flags, data_size;

		stream->type = ASF_STREAM_TYPE_VIDEO;

		if (datalen < 51) {
			return ASF_ERROR_INVALID_LENGTH;
		}

		width = asf_byteio_getDWLE(data);
		height = asf_byteio_getDWLE(data + 4);
		flags = data[8];
		data_size = asf_byteio_getWLE(data + 9);

		data += 11;
		datalen -= 11;

		if (asf_byteio_getDWLE(data) != datalen) {
			return ASF_ERROR_INVALID_LENGTH;
		}
		if (width != asf_byteio_getDWLE(data + 4) ||
		    height != asf_byteio_getDWLE(data + 8) ||
		    flags != 2) {
			return ASF_ERROR_INVALID_VALUE;
		}

		/* this should be freed in asf_close function */
		stream->properties = malloc(sizeof(asf_bitmapinfoheader_t));
		if (!stream->properties)
			return ASF_ERROR_OUTOFMEM;
		stream->flags |= ASF_STREAM_FLAG_AVAILABLE;

		bmih = stream->properties;
		bmih->biSize = asf_byteio_getDWLE(data);
		bmih->biWidth = asf_byteio_getDWLE(data + 4);
		bmih->biHeight = asf_byteio_getDWLE(data + 8);
		bmih->biPlanes = asf_byteio_getDWLE(data + 12);
		bmih->biBitCount = asf_byteio_getDWLE(data + 14);
		bmih->biCompression = asf_byteio_getDWLE(data + 16);
		bmih->biSizeImage = asf_byteio_getDWLE(data + 20);
		bmih->biXPelsPerMeter = asf_byteio_getDWLE(data + 24);
		bmih->biYPelsPerMeter = asf_byteio_getDWLE(data + 28);
		bmih->biClrUsed = asf_byteio_getDWLE(data + 32);
		bmih->biClrImportant = asf_byteio_getDWLE(data + 36);
		bmih->data = data + 40;

		if (bmih->biSize > datalen) {
			debug_printf("Invalid bitmapinfoheader data length, truncating!");
			bmih->biSize = datalen;
		}

		break;
	}
	case GUID_STREAM_TYPE_COMMAND:
		stream->type = ASF_STREAM_TYPE_COMMAND;
		break;
	default:
		stream->type = ASF_STREAM_TYPE_UNKNOWN;
		break;
	}

	return 0;
}