[Scummvm-cvs-logs] SF.net SVN: scummvm:[52408] scummvm/trunk/graphics/video/codecs
drmccoy at users.sourceforge.net
drmccoy at users.sourceforge.net
Fri Aug 27 12:45:20 CEST 2010
Revision: 52408
http://scummvm.svn.sourceforge.net/scummvm/?rev=52408&view=rev
Author: drmccoy
Date: 2010-08-27 10:45:19 +0000 (Fri, 27 Aug 2010)
Log Message:
-----------
VIDEO: Change decodeImage() around a bit, plug a leak
Indeo3Decoder::decoderImage() was leaking inData
Modified Paths:
--------------
scummvm/trunk/graphics/video/codecs/indeo3.cpp
scummvm/trunk/graphics/video/codecs/indeo3.h
Modified: scummvm/trunk/graphics/video/codecs/indeo3.cpp
===================================================================
--- scummvm/trunk/graphics/video/codecs/indeo3.cpp 2010-08-27 10:01:09 UTC (rev 52407)
+++ scummvm/trunk/graphics/video/codecs/indeo3.cpp 2010-08-27 10:45:19 UTC (rev 52408)
@@ -69,27 +69,22 @@
return _pixelFormat;
}
-bool Indeo3Decoder::isIndeo3(byte *data, uint32 dataLen) {
- // No data, no Indeo 3
- if (!data)
- return false;
-
+bool Indeo3Decoder::isIndeo3(Common::SeekableReadStream &stream) {
// Less than 16 bytes? This can't be right
- if (dataLen < 16)
+ if (stream.size() < 16)
return false;
+ uint32 id0 = stream.readUint32LE();
+ uint32 id1 = stream.readUint32LE();
+ uint32 id2 = stream.readUint32LE();
+ uint32 id3 = stream.readUint32LE();
+
// Unknown, but according to the docs, always 0
- if (READ_LE_UINT32(data + 4) != 0)
+ if (id1 != 0)
return false;
- uint32 id;
- id = READ_LE_UINT32(data ); // frame number
- id ^= READ_LE_UINT32(data + 4); // unknown
- id ^= READ_LE_UINT32(data + 8); // checksum
- id ^= READ_LE_UINT32(data + 12); // frame data length
-
// These 4 uint32s XOR'd need to spell "FRMH"
- if (id != MKID_BE('FRMH'))
+ if ((id0 ^ id1 ^ id2 ^ id3) != MKID_BE('FRMH'))
return false;
return true;
@@ -174,32 +169,24 @@
}
Surface *Indeo3Decoder::decodeImage(Common::SeekableReadStream *stream) {
- uint32 dataLen = stream->size();
-
- byte *inData = new byte[dataLen];
-
- if (stream->read(inData, dataLen) != dataLen)
- return 0;
-
// Not Indeo 3? Fail
- if (!isIndeo3(inData, dataLen))
+ if (!isIndeo3(*stream))
return 0;
- uint32 frameDataLen = READ_LE_UINT32(inData + 12);
+ stream->seek(12);
+ uint32 frameDataLen = stream->readUint32LE();
// Less data than the frame should have? Fail
- if (dataLen < (frameDataLen - 16))
+ if (stream->size() < (int)(frameDataLen - 16))
return 0;
- Common::MemoryReadStream frame(inData, dataLen);
+ stream->seek(16); // Behind header
+ stream->skip(2); // Unknown
- frame.skip(16); // Header
- frame.skip(2); // Unknown
+ uint16 flags1 = stream->readUint16LE();
+ uint32 flags3 = stream->readUint32LE();
+ uint8 flags2 = stream->readByte();
- uint16 flags1 = frame.readUint16LE();
- uint32 flags3 = frame.readUint32LE();
- uint8 flags2 = frame.readByte();
-
// Finding the reference frame
if (flags1 & 0x200) {
_cur_frame = _iv_frame + 1;
@@ -212,47 +199,71 @@
if (flags3 == 0x80)
return _surface;
- frame.skip(3);
+ stream->skip(3);
- uint16 fHeight = frame.readUint16LE();
- uint16 fWidth = frame.readUint16LE();
+ uint16 fHeight = stream->readUint16LE();
+ uint16 fWidth = stream->readUint16LE();
uint32 chromaHeight = ((fHeight >> 2) + 3) & 0x7FFC;
uint32 chromaWidth = ((fWidth >> 2) + 3) & 0x7FFC;
uint32 offs;
- uint32 offsY = frame.readUint32LE() + 16;
- uint32 offsU = frame.readUint32LE() + 16;
- uint32 offsV = frame.readUint32LE() + 16;
+ uint32 offsY = stream->readUint32LE() + 16;
+ uint32 offsU = stream->readUint32LE() + 16;
+ uint32 offsV = stream->readUint32LE() + 16;
- frame.skip(4);
+ stream->skip(4);
- uint32 hPos = frame.pos();
+ uint32 hPos = stream->pos();
- byte *hdr_pos = inData + hPos;
+ if (offsY < hPos) {
+ warning("Indeo3Decoder::decodeImage: offsY < hPos");
+ return 0;
+ }
+ if (offsU < hPos) {
+ warning("Indeo3Decoder::decodeImage: offsY < hPos");
+ return 0;
+ }
+ if (offsV < hPos) {
+ warning("Indeo3Decoder::decodeImage: offsY < hPos");
+ return 0;
+ }
+
+ uint32 dataSize = stream->size() - hPos;
+
+ byte *inData = new byte[dataSize];
+
+ if (stream->read(inData, dataSize) != dataSize) {
+ delete[] inData;
+ return 0;
+ }
+
+ byte *hdr_pos = inData;
byte *buf_pos;
// Luminance Y
- frame.seek(offsY);
- buf_pos = inData + offsY + 4;
- offs = frame.readUint32LE();
+ stream->seek(offsY);
+ buf_pos = inData + offsY + 4 - hPos;
+ offs = stream->readUint32LE();
decodeChunk(_cur_frame->Ybuf, _ref_frame->Ybuf, fWidth, fHeight,
buf_pos + offs * 2, flags2, hdr_pos, buf_pos, MIN<int>(fWidth, 160));
// Chrominance U
- frame.seek(offsU);
- buf_pos = inData + offsU + 4;
- offs = frame.readUint32LE();
+ stream->seek(offsU);
+ buf_pos = inData + offsU + 4 - hPos;
+ offs = stream->readUint32LE();
decodeChunk(_cur_frame->Vbuf, _ref_frame->Vbuf, chromaWidth, chromaHeight,
buf_pos + offs * 2, flags2, hdr_pos, buf_pos, MIN<int>(chromaWidth, 40));
// Chrominance V
- frame.seek(offsV);
- buf_pos = inData + offsV + 4;
- offs = frame.readUint32LE();
+ stream->seek(offsV);
+ buf_pos = inData + offsV + 4 - hPos;
+ offs = stream->readUint32LE();
decodeChunk(_cur_frame->Ubuf, _ref_frame->Ubuf, chromaWidth, chromaHeight,
buf_pos + offs * 2, flags2, hdr_pos, buf_pos, MIN<int>(chromaWidth, 40));
+ delete[] inData;
+
// Blit the frame onto the surface
const byte *srcY = _cur_frame->Ybuf;
const byte *srcU = _cur_frame->Ubuf;
Modified: scummvm/trunk/graphics/video/codecs/indeo3.h
===================================================================
--- scummvm/trunk/graphics/video/codecs/indeo3.h 2010-08-27 10:01:09 UTC (rev 52407)
+++ scummvm/trunk/graphics/video/codecs/indeo3.h 2010-08-27 10:45:19 UTC (rev 52408)
@@ -49,7 +49,7 @@
Surface *decodeImage(Common::SeekableReadStream *stream);
PixelFormat getPixelFormat() const;
- static bool isIndeo3(byte *data, uint32 dataLen);
+ static bool isIndeo3(Common::SeekableReadStream &stream);
private:
Surface *_surface;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list