diff options
author | Matthew Hoops | 2012-04-05 23:12:19 -0400 |
---|---|---|
committer | D G Turner | 2012-04-08 03:29:40 +0100 |
commit | b0646529d1d36a2bc8113ccc21da0c7efc738288 (patch) | |
tree | ffe1d187b7e693fd7f1cc708f9fcfa38691c6533 | |
parent | 7e0510725656323513bbe4f51f8164f916a52936 (diff) | |
download | scummvm-rg350-b0646529d1d36a2bc8113ccc21da0c7efc738288.tar.gz scummvm-rg350-b0646529d1d36a2bc8113ccc21da0c7efc738288.tar.bz2 scummvm-rg350-b0646529d1d36a2bc8113ccc21da0c7efc738288.zip |
VIDEO: Fix segfaults on different sized SVQ1 frames
-rw-r--r-- | video/codecs/svq1.cpp | 54 | ||||
-rw-r--r-- | video/codecs/svq1.h | 4 |
2 files changed, 32 insertions, 26 deletions
diff --git a/video/codecs/svq1.cpp b/video/codecs/svq1.cpp index d5baaba37e..628172226c 100644 --- a/video/codecs/svq1.cpp +++ b/video/codecs/svq1.cpp @@ -48,8 +48,8 @@ SVQ1Decoder::SVQ1Decoder(uint16 width, uint16 height) { debug(1, "SVQ1Decoder::SVQ1Decoder(width:%d, height:%d)", width, height); _width = width; _height = height; - _surface = new Graphics::Surface(); - _surface->create(width, height, g_system->getScreenFormat()); + _frameWidth = _frameHeight = 0; + _surface = 0; _last[0] = 0; _last[1] = 0; @@ -69,8 +69,10 @@ SVQ1Decoder::SVQ1Decoder(uint16 width, uint16 height) { } SVQ1Decoder::~SVQ1Decoder() { - _surface->free(); - delete _surface; + if (_surface) { + _surface->free(); + delete _surface; + } delete[] _last[0]; delete[] _last[1]; @@ -230,19 +232,23 @@ const Graphics::Surface *SVQ1Decoder::decodeImage(Common::SeekableReadStream *st byte frameSizeCode = frameData.getBits(3); debug(1, " frameSizeCode: %d", frameSizeCode); - uint16 frameWidth, frameHeight; + if (frameSizeCode == 7) { - frameWidth = frameData.getBits(12); - frameHeight = frameData.getBits(12); + _frameWidth = frameData.getBits(12); + _frameHeight = frameData.getBits(12); } else { - frameWidth = standardFrameSizes[frameSizeCode].w; - frameHeight = standardFrameSizes[frameSizeCode].h; + _frameWidth = standardFrameSizes[frameSizeCode].w; + _frameHeight = standardFrameSizes[frameSizeCode].h; } - debug(1, " frameWidth: %d", frameWidth); - debug(1, " frameHeight: %d", frameHeight); - if (frameWidth != _width || frameHeight != _height) { // Invalid - warning("Invalid Frame Size"); - return _surface; + debug(1, " frameWidth: %d", _frameWidth); + debug(1, " frameHeight: %d", _frameHeight); + + // Now we'll create the surface + if (!_surface) { + _surface = new Graphics::Surface(); + _surface->create(_frameWidth, _frameHeight, g_system->getScreenFormat()); + _surface->w = _width; + _surface->h = _height; } } else if (frameType == 2) { // B Frame warning("B Frames not supported by SVQ1 decoder"); @@ -285,47 +291,47 @@ const Graphics::Surface *SVQ1Decoder::decodeImage(Common::SeekableReadStream *st byte *current[3]; // FIXME - Added extra _width of 16px blocks to stop out of // range access causing crashes. Need to correct code... - current[0] = new byte[_width*_height +(_width*16)]; - current[1] = new byte[(_width/4)*(_height/4) +(_width/4*16)]; - current[2] = new byte[(_width/4)*(_height/4) +(_width/4*16)]; + current[0] = new byte[_frameWidth * _frameHeight + (_frameWidth * 16)]; + current[1] = new byte[(_frameWidth / 4) * (_frameHeight / 4) + (_frameWidth / 4 * 16)]; + current[2] = new byte[(_frameWidth / 4) * (_frameHeight / 4) + (_frameWidth / 4 * 16)]; // Decode Y, U and V component planes for (int i = 0; i < 3; i++) { int linesize, width, height; if (i == 0) { // Y Size is width * height - width = _width; + width = _frameWidth; if (width % 16) { width /= 16; width++; width *= 16; } assert(width % 16 == 0); - height = _height; + height = _frameHeight; if (height % 16) { height /= 16; height++; height *= 16; } assert(height % 16 == 0); - linesize = _width; + linesize = _frameWidth; } else { // U and V size is width/4 * height/4 - width = _width/4; + width = _frameWidth / 4; if (width % 16) { width /= 16; width++; width *= 16; } assert(width % 16 == 0); - height = _height/4; + height = _frameHeight / 4; if (height % 16) { height /= 16; height++; height *= 16; } assert(height % 16 == 0); - linesize = _width/4; + linesize = _frameWidth / 4; } if (frameType == 0) { // I Frame @@ -370,7 +376,7 @@ const Graphics::Surface *SVQ1Decoder::decodeImage(Common::SeekableReadStream *st } } - convertYUV410ToRGB(_surface, current[0], current[1], current[2], _width, _height, _width, _width/4); + convertYUV410ToRGB(_surface, current[0], current[1], current[2], _frameWidth, _frameHeight, _frameWidth, _frameWidth / 4); for (int i = 0; i < 3; i++) { delete[] _last[i]; diff --git a/video/codecs/svq1.h b/video/codecs/svq1.h index ed34439329..8442f07e4e 100644 --- a/video/codecs/svq1.h +++ b/video/codecs/svq1.h @@ -43,8 +43,8 @@ public: private: Graphics::Surface *_surface; - uint16 _width; - uint16 _height; + uint16 _width, _height; + uint16 _frameWidth, _frameHeight; byte *_last[3]; |