aboutsummaryrefslogtreecommitdiff
path: root/engines/zvision/video/rlf_decoder.cpp
diff options
context:
space:
mode:
authorFilippos Karapetis2014-12-16 00:48:16 +0200
committerFilippos Karapetis2014-12-16 01:58:55 +0200
commit7f61a094781256f7c2734aa08637494c1dfac6bf (patch)
tree2dd89d28d338daeb8bdf06e41bcc9e5768cf9885 /engines/zvision/video/rlf_decoder.cpp
parent67bd78a95f6efab6d0da4b3bef1b0cebc79c537c (diff)
downloadscummvm-rg350-7f61a094781256f7c2734aa08637494c1dfac6bf.tar.gz
scummvm-rg350-7f61a094781256f7c2734aa08637494c1dfac6bf.tar.bz2
scummvm-rg350-7f61a094781256f7c2734aa08637494c1dfac6bf.zip
ZVISION: Make the RLF decoder a subclass of the common video decoder
This way, the redundant MetaAnimation class can now be removed
Diffstat (limited to 'engines/zvision/video/rlf_decoder.cpp')
-rw-r--r--engines/zvision/video/rlf_decoder.cpp141
1 files changed, 44 insertions, 97 deletions
diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp
index a4f16af9b0..bdb5dc18bc 100644
--- a/engines/zvision/video/rlf_decoder.cpp
+++ b/engines/zvision/video/rlf_decoder.cpp
@@ -34,75 +34,46 @@
namespace ZVision {
-RLFDecoder::RLFDecoder(const Common::String &fileName, bool stream)
- : _stream(stream),
- _readStream(NULL),
- _lastFrameRead(0),
- _frameCount(0),
- _width(0),
- _height(0),
- _frameTime(0),
- _frames(0),
- _nextFrame(0),
- _frameBufferByteSize(0) {
-
- Common::File *_file = new Common::File;
- if (!_file->open(fileName)) {
- warning("RLF animation file %s could not be opened", fileName.c_str());
- return;
- }
-
- _readStream = _file;
-
- if (!readHeader()) {
- warning("%s is not a RLF animation file. Wrong magic number", fileName.c_str());
- return;
- }
+RLFDecoder::~RLFDecoder() {
+ close();
+}
- _currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>());
- _frameBufferByteSize = _width * _height * sizeof(uint16);
+bool RLFDecoder::loadStream(Common::SeekableReadStream *stream) {
+ close();
- if (!stream) {
- _frames = new Frame[_frameCount];
+ addTrack(new RLFVideoTrack(stream));
- // Read in each frame
- for (uint i = 0; i < _frameCount; ++i) {
- _frames[i] = readNextFrame();
- }
- }
+ return true;
}
-RLFDecoder::RLFDecoder(Common::SeekableReadStream *rstream, bool stream)
- : _stream(stream),
- _readStream(rstream),
+RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream)
+ : _readStream(stream),
_lastFrameRead(0),
_frameCount(0),
_width(0),
_height(0),
_frameTime(0),
_frames(0),
- _nextFrame(0),
+ _curFrame(0),
_frameBufferByteSize(0) {
if (!readHeader()) {
- warning("Stream is not a RLF animation. Wrong magic number");
+ warning("Not a RLF animation file. Wrong magic number");
return;
}
_currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>());
_frameBufferByteSize = _width * _height * sizeof(uint16);
- if (!stream) {
- _frames = new Frame[_frameCount];
+ _frames = new Frame[_frameCount];
- // Read in each frame
- for (uint i = 0; i < _frameCount; ++i) {
- _frames[i] = readNextFrame();
- }
+ // Read in each frame
+ for (uint i = 0; i < _frameCount; ++i) {
+ _frames[i] = readNextFrame();
}
}
-RLFDecoder::~RLFDecoder() {
+RLFDecoder::RLFVideoTrack::~RLFVideoTrack() {
for (uint i = 0; i < _frameCount; ++i) {
delete[] _frames[i].encodedData;
}
@@ -111,7 +82,7 @@ RLFDecoder::~RLFDecoder() {
_currentFrameBuffer.free();
}
-bool RLFDecoder::readHeader() {
+bool RLFDecoder::RLFVideoTrack::readHeader() {
if (_readStream->readUint32BE() != MKTAG('F', 'E', 'L', 'R')) {
return false;
}
@@ -160,8 +131,8 @@ bool RLFDecoder::readHeader() {
return true;
}
-RLFDecoder::Frame RLFDecoder::readNextFrame() {
- RLFDecoder::Frame frame;
+RLFDecoder::RLFVideoTrack::Frame RLFDecoder::RLFVideoTrack::readNextFrame() {
+ RLFDecoder::RLFVideoTrack::Frame frame;
_readStream->readUint32BE(); // Magic number MARF
uint32 size = _readStream->readUint32LE(); // Size
@@ -188,30 +159,30 @@ RLFDecoder::Frame RLFDecoder::readNextFrame() {
return frame;
}
-void RLFDecoder::seekToFrame(int frameNumber) {
- assert(!_stream);
- assert(frameNumber < (int)_frameCount || frameNumber >= -1);
+bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) {
+ uint frame = getFrameAtTime(time);
+ assert(frame < (int)_frameCount);
- if (_nextFrame == frameNumber)
- return;
+ if ((uint)_curFrame == frame)
+ return true;
- if (frameNumber < 0) {
- _nextFrame = 0;
- return;
+ if (frame < 0) {
+ _curFrame = 0;
+ return false;
}
- int closestFrame = _nextFrame;
- int distance = (int)frameNumber - _nextFrame;
+ int closestFrame = _curFrame;
+ int distance = (int)frame - _curFrame;
if (distance < 0) {
for (uint i = 0; i < _completeFrames.size(); ++i) {
- if ((int)_completeFrames[i] > frameNumber)
+ if ((int)_completeFrames[i] > frame)
break;
closestFrame = _completeFrames[i];
}
} else {
for (uint i = 0; i < _completeFrames.size(); ++i) {
- int newDistance = (int)frameNumber - (int)(_completeFrames[i]);
+ int newDistance = (int)frame - (int)(_completeFrames[i]);
if (newDistance < 0)
break;
if (newDistance < distance) {
@@ -221,43 +192,27 @@ void RLFDecoder::seekToFrame(int frameNumber) {
}
}
- for (int i = closestFrame; i < frameNumber; ++i) {
+ for (uint i = closestFrame; i < frame; ++i) {
applyFrameToCurrent(i);
}
- _nextFrame = frameNumber;
-}
-
-const Graphics::Surface *RLFDecoder::getFrameData(uint frameNumber) {
- assert(!_stream);
- assert(frameNumber < _frameCount);
+ _curFrame = frame;
- // Since this method is so expensive, first check to see if we can use
- // decodeNextFrame() it's cheap.
- if ((int)frameNumber == _nextFrame - 1) {
- return &_currentFrameBuffer;
- } else if (_nextFrame == (int)frameNumber) {
- return decodeNextFrame();
- }
-
- seekToFrame(frameNumber);
- return decodeNextFrame();
+ return true;
}
-const Graphics::Surface *RLFDecoder::decodeNextFrame() {
- assert(_nextFrame < (int)_frameCount);
+const Graphics::Surface *RLFDecoder::RLFVideoTrack::decodeNextFrame() {
+ // When an animation ends, rewind
+ if (_curFrame == (int)_frameCount)
+ seek(Audio::Timestamp(0, getFrameRate().toInt()));
+
+ applyFrameToCurrent(_curFrame);
- if (_stream) {
- applyFrameToCurrent(readNextFrame());
- } else {
- applyFrameToCurrent(_nextFrame);
- }
-
- _nextFrame++;
+ _curFrame++;
return &_currentFrameBuffer;
}
-void RLFDecoder::applyFrameToCurrent(uint frameNumber) {
+void RLFDecoder::RLFVideoTrack::applyFrameToCurrent(uint frameNumber) {
if (_frames[frameNumber].type == Masked) {
decodeMaskedRunLengthEncoding(_frames[frameNumber].encodedData, (int8 *)_currentFrameBuffer.getPixels(), _frames[frameNumber].encodedSize, _frameBufferByteSize);
} else if (_frames[frameNumber].type == Simple) {
@@ -265,15 +220,7 @@ void RLFDecoder::applyFrameToCurrent(uint frameNumber) {
}
}
-void RLFDecoder::applyFrameToCurrent(const RLFDecoder::Frame &frame) {
- if (frame.type == Masked) {
- decodeMaskedRunLengthEncoding(frame.encodedData, (int8 *)_currentFrameBuffer.getPixels(), frame.encodedSize, _frameBufferByteSize);
- } else if (frame.type == Simple) {
- decodeSimpleRunLengthEncoding(frame.encodedData, (int8 *)_currentFrameBuffer.getPixels(), frame.encodedSize, _frameBufferByteSize);
- }
-}
-
-void RLFDecoder::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
+void RLFDecoder::RLFVideoTrack::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
uint32 sourceOffset = 0;
uint32 destOffset = 0;
int16 numberOfCopy = 0;
@@ -320,7 +267,7 @@ void RLFDecoder::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32
}
}
-void RLFDecoder::decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
+void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const {
uint32 sourceOffset = 0;
uint32 destOffset = 0;
int16 numberOfCopy = 0;