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; }
/** * 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; }