From 5a3b9d3daf64ea686427478391d3773c5a1e024e Mon Sep 17 00:00:00 2001 From: Justin McPherson Date: Thu, 4 Mar 2010 17:26:19 +1000 Subject: WaveDecoder; be more permissive in handling of wave file formats. Reviewed-by: Dmytro Poplavskiy --- src/multimedia/effects/wavedecoder_p.cpp | 21 ++++++++++++++++----- src/multimedia/effects/wavedecoder_p.h | 1 - 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/multimedia/effects/wavedecoder_p.cpp b/src/multimedia/effects/wavedecoder_p.cpp index f2277ae..b534ded 100644 --- a/src/multimedia/effects/wavedecoder_p.cpp +++ b/src/multimedia/effects/wavedecoder_p.cpp @@ -55,7 +55,7 @@ WaveDecoder::WaveDecoder(QIODevice *s, QObject *parent): { open(QIODevice::ReadOnly | QIODevice::Unbuffered); - if (source->bytesAvailable() >= sizeof(CombinedHeader)) + if (source->bytesAvailable() >= qint64(sizeof(CombinedHeader) + sizeof(DATAHeader) + sizeof(quint16))) QTimer::singleShot(0, this, SLOT(handleData())); else connect(source, SIGNAL(readyRead()), SLOT(handleData())); @@ -105,7 +105,7 @@ qint64 WaveDecoder::writeData(const char *data, qint64 len) void WaveDecoder::handleData() { - if (source->bytesAvailable() < sizeof(CombinedHeader)) + if (source->bytesAvailable() < qint64(sizeof(CombinedHeader) + sizeof(DATAHeader) + sizeof(quint16))) return; source->disconnect(SIGNAL(readyRead()), this, SLOT(handleData())); @@ -114,12 +114,23 @@ void WaveDecoder::handleData() if (qstrncmp(header.riff.descriptor.id, "RIFF", 4) != 0 || qstrncmp(header.riff.type, "WAVE", 4) != 0 || qstrncmp(header.wave.descriptor.id, "fmt ", 4) != 0 || - (header.wave.audioFormat != 0 && header.wave.audioFormat != 1) || - qstrncmp(header.data.descriptor.id, "data", 4) != 0) { + (header.wave.audioFormat != 0 && header.wave.audioFormat != 1)) { emit invalidFormat(); } else { + DATAHeader dataHeader; + + if (qFromLittleEndian(header.wave.descriptor.size) > sizeof(WAVEHeader)) { + // Extended data available + quint16 extraFormatBytes; + source->peek((char*)&extraFormatBytes, sizeof(quint16)); + extraFormatBytes = qFromLittleEndian(extraFormatBytes); + source->read(sizeof(quint16) + extraFormatBytes); // dump it all + } + + source->read((char*)&dataHeader, sizeof(DATAHeader)); + int bps = qFromLittleEndian(header.wave.bitsPerSample); format.setCodec(QLatin1String("audio/pcm")); @@ -129,7 +140,7 @@ void WaveDecoder::handleData() format.setSampleSize(bps); format.setChannels(qFromLittleEndian(header.wave.numChannels)); - dataSize = qFromLittleEndian(header.data.descriptor.size); + dataSize = qFromLittleEndian(dataHeader.descriptor.size); haveFormat = true; connect(source, SIGNAL(readyRead()), SIGNAL(readyRead())); diff --git a/src/multimedia/effects/wavedecoder_p.h b/src/multimedia/effects/wavedecoder_p.h index 00aa14e..fa1f77e 100644 --- a/src/multimedia/effects/wavedecoder_p.h +++ b/src/multimedia/effects/wavedecoder_p.h @@ -116,7 +116,6 @@ private: { RIFFHeader riff; WAVEHeader wave; - DATAHeader data; }; bool haveFormat; -- cgit v0.12