summaryrefslogtreecommitdiffstats
path: root/src/multimedia
diff options
context:
space:
mode:
authorJustin McPherson <justin.mcpherson@nokia.com>2010-03-04 07:26:19 (GMT)
committerJustin McPherson <justin.mcpherson@nokia.com>2010-03-04 07:32:59 (GMT)
commit5a3b9d3daf64ea686427478391d3773c5a1e024e (patch)
treebc7ce3bc52c142c83dad59fbe71564ac01c49713 /src/multimedia
parent53af250a5366b4259bfb97a6b3c29c31e0aa10e0 (diff)
downloadQt-5a3b9d3daf64ea686427478391d3773c5a1e024e.zip
Qt-5a3b9d3daf64ea686427478391d3773c5a1e024e.tar.gz
Qt-5a3b9d3daf64ea686427478391d3773c5a1e024e.tar.bz2
WaveDecoder; be more permissive in handling of wave file formats.
Reviewed-by: Dmytro Poplavskiy
Diffstat (limited to 'src/multimedia')
-rw-r--r--src/multimedia/effects/wavedecoder_p.cpp21
-rw-r--r--src/multimedia/effects/wavedecoder_p.h1
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<quint32>(header.wave.descriptor.size) > sizeof(WAVEHeader)) {
+ // Extended data available
+ quint16 extraFormatBytes;
+ source->peek((char*)&extraFormatBytes, sizeof(quint16));
+ extraFormatBytes = qFromLittleEndian<quint16>(extraFormatBytes);
+ source->read(sizeof(quint16) + extraFormatBytes); // dump it all
+ }
+
+ source->read((char*)&dataHeader, sizeof(DATAHeader));
+
int bps = qFromLittleEndian<quint16>(header.wave.bitsPerSample);
format.setCodec(QLatin1String("audio/pcm"));
@@ -129,7 +140,7 @@ void WaveDecoder::handleData()
format.setSampleSize(bps);
format.setChannels(qFromLittleEndian<quint16>(header.wave.numChannels));
- dataSize = qFromLittleEndian<quint32>(header.data.descriptor.size);
+ dataSize = qFromLittleEndian<quint32>(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;