* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stdint.h>
+
#include "libavutil/avassert.h"
#include "libavutil/dict.h"
#include "libavutil/log.h"
return avio_rl32(pb);
}
+/* RIFF chunks are always on a even offset. */
+static int64_t wav_seek_tag(AVIOContext *s, int64_t offset, int whence)
+{
+ return avio_seek(s, offset + (offset & 1), whence);
+}
+
/* return the size of the found tag */
static int64_t find_tag(AVIOContext *pb, uint32_t tag1)
{
size = next_tag(pb, &tag);
if (tag == tag1)
break;
- avio_skip(pb, size);
+ wav_seek_tag(pb, size, SEEK_CUR);
}
return size;
}
rf64 = tag == MKTAG('R', 'F', '6', '4');
if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F'))
- return -1;
+ return AVERROR_INVALIDDATA;
avio_rl32(pb); /* file size */
tag = avio_rl32(pb);
if (tag != MKTAG('W', 'A', 'V', 'E'))
- return -1;
+ return AVERROR_INVALIDDATA;
if (rf64) {
if (avio_rl32(pb) != MKTAG('d', 's', '6', '4'))
- return -1;
+ return AVERROR_INVALIDDATA;
size = avio_rl32(pb);
if (size < 16)
- return -1;
+ return AVERROR_INVALIDDATA;
avio_rl64(pb); /* RIFF size */
data_size = avio_rl64(pb);
/* seek to next tag unless we know that we'll run into EOF */
if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) ||
- avio_seek(pb, next_tag_ofs, SEEK_SET) < 0) {
+ wav_seek_tag(pb, next_tag_ofs, SEEK_SET) < 0) {
break;
}
}
avio_read(pb, guid, 16);
if (memcmp(guid, guid_riff, 16))
- return -1;
+ return AVERROR_INVALIDDATA;
/* riff + wave + fmt + sizes */
if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8)
- return -1;
+ return AVERROR_INVALIDDATA;
avio_read(pb, guid, 16);
if (memcmp(guid, guid_wave, 16)) {
av_log(s, AV_LOG_ERROR, "could not find wave guid\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
size = find_guid(pb, guid_fmt);
if (size < 0) {
av_log(s, AV_LOG_ERROR, "could not find fmt guid\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
st = avformat_new_stream(s, NULL);
size = find_guid(pb, guid_data);
if (size < 0) {
av_log(s, AV_LOG_ERROR, "could not find data guid\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
wav->data_end = avio_tell(pb) + size - 24;
wav->w64 = 1;