diff options
author | Filippos Karapetis | 2016-10-03 00:18:39 +0300 |
---|---|---|
committer | Filippos Karapetis | 2016-10-03 00:33:49 +0300 |
commit | 7331bdc6b1f15bc9f5c8e186d4f19923c1c723a4 (patch) | |
tree | 0fc0f35c5a959e9a92f22bd99c6d0400555ff018 | |
parent | 0152b7c47f0eef04bd01ae6e1cb808d25ccdd9a0 (diff) | |
download | scummvm-rg350-7331bdc6b1f15bc9f5c8e186d4f19923c1c723a4.tar.gz scummvm-rg350-7331bdc6b1f15bc9f5c8e186d4f19923c1c723a4.tar.bz2 scummvm-rg350-7331bdc6b1f15bc9f5c8e186d4f19923c1c723a4.zip |
VIDEO: Allow parts of the FLIC decoder to be overriden by child classes
This is needed by the specialized FLIC video decoder used in the chewy
engine
-rw-r--r-- | video/flic_decoder.cpp | 148 | ||||
-rw-r--r-- | video/flic_decoder.h | 18 |
2 files changed, 87 insertions, 79 deletions
diff --git a/video/flic_decoder.cpp b/video/flic_decoder.cpp index 994f47cea8..a1976e2729 100644 --- a/video/flic_decoder.cpp +++ b/video/flic_decoder.cpp @@ -85,19 +85,10 @@ void FlicDecoder::copyDirtyRectsToBuffer(uint8 *dst, uint pitch) { ((FlicVideoTrack *)track)->copyDirtyRectsToBuffer(dst, pitch); } -FlicDecoder::FlicVideoTrack::FlicVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height) { +FlicDecoder::FlicVideoTrack::FlicVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height, bool skipHeader) { _fileStream = stream; _frameCount = frameCount; - _fileStream->readUint16LE(); // flags - // Note: The normal delay is a 32-bit integer (dword), whereas the overridden delay is a 16-bit integer (word) - // the frame delay is the FLIC "speed", in milliseconds. - _frameDelay = _startFrameDelay = _fileStream->readUint32LE(); - - _fileStream->seek(80); - _offsetFrame1 = _fileStream->readUint32LE(); - _offsetFrame2 = _fileStream->readUint32LE(); - _surface = new Graphics::Surface(); _surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); _palette = new byte[3 * 256]; @@ -108,8 +99,8 @@ FlicDecoder::FlicVideoTrack::FlicVideoTrack(Common::SeekableReadStream *stream, _nextFrameStartTime = 0; _atRingFrame = false; - // Seek to the first frame - _fileStream->seek(_offsetFrame1); + if (!skipHeader) + readHeader(); } FlicDecoder::FlicVideoTrack::~FlicVideoTrack() { @@ -120,6 +111,20 @@ FlicDecoder::FlicVideoTrack::~FlicVideoTrack() { delete _surface; } +void FlicDecoder::FlicVideoTrack::readHeader() { + _fileStream->readUint16LE(); // flags + // Note: The normal delay is a 32-bit integer (dword), whereas the overridden delay is a 16-bit integer (word) + // the frame delay is the FLIC "speed", in milliseconds. + _frameDelay = _startFrameDelay = _fileStream->readUint32LE(); + + _fileStream->seek(80); + _offsetFrame1 = _fileStream->readUint32LE(); + _offsetFrame2 = _fileStream->readUint32LE(); + + // Seek to the first frame + _fileStream->seek(_offsetFrame1); +} + bool FlicDecoder::FlicVideoTrack::endOfTrack() const { return getCurFrame() >= getFrameCount() - 1; } @@ -158,76 +163,18 @@ Graphics::PixelFormat FlicDecoder::FlicVideoTrack::getPixelFormat() const { const Graphics::Surface *FlicDecoder::FlicVideoTrack::decodeNextFrame() { // Read chunk - uint32 frameSize = _fileStream->readUint32LE(); + /*uint32 frameSize = */ _fileStream->readUint32LE(); uint16 frameType = _fileStream->readUint16LE(); - uint16 chunkCount = 0; switch (frameType) { case FRAME_TYPE: - { - chunkCount = _fileStream->readUint16LE(); - // Note: The overridden delay is a 16-bit integer (word), whereas the normal delay is a 32-bit integer (dword) - // the frame delay is the FLIC "speed", in milliseconds. - uint16 newFrameDelay = _fileStream->readUint16LE(); // "speed", in milliseconds - if (newFrameDelay > 0) - _frameDelay = newFrameDelay; - - _fileStream->readUint16LE(); // reserved, always 0 - uint16 newWidth = _fileStream->readUint16LE(); - uint16 newHeight = _fileStream->readUint16LE(); - - if ((newWidth != 0) || (newHeight != 0)) { - if (newWidth == 0) - newWidth = _surface->w; - if (newHeight == 0) - newHeight = _surface->h; - - _surface->free(); - delete _surface; - _surface = new Graphics::Surface(); - _surface->create(newWidth, newHeight, Graphics::PixelFormat::createFormatCLUT8()); - } - } + handleFrame(); break; default: error("FlicDecoder::decodeFrame(): unknown main chunk type (type = 0x%02X)", frameType); break; } - // Read subchunks - if (frameType == FRAME_TYPE) { - for (uint32 i = 0; i < chunkCount; ++i) { - frameSize = _fileStream->readUint32LE(); - frameType = _fileStream->readUint16LE(); - uint8 *data = new uint8[frameSize - 6]; - _fileStream->read(data, frameSize - 6); - - switch (frameType) { - case FLI_SETPAL: - unpackPalette(data); - _dirtyPalette = true; - break; - case FLI_SS2: - decodeDeltaFLC(data); - break; - case FLI_BRUN: - decodeByteRun(data); - break; - case FLI_COPY: - copyFrame(data); - break; - case PSTAMP: - /* PSTAMP - skip for now */ - break; - default: - error("FlicDecoder::decodeNextFrame(): unknown subchunk type (type = 0x%02X)", frameType); - break; - } - - delete[] data; - } - } - _curFrame++; _nextFrameStartTime += _frameDelay; @@ -240,6 +187,63 @@ const Graphics::Surface *FlicDecoder::FlicVideoTrack::decodeNextFrame() { return _surface; } +void FlicDecoder::FlicVideoTrack::handleFrame() { + uint16 chunkCount = _fileStream->readUint16LE(); + // Note: The overridden delay is a 16-bit integer (word), whereas the normal delay is a 32-bit integer (dword) + // the frame delay is the FLIC "speed", in milliseconds. + uint16 newFrameDelay = _fileStream->readUint16LE(); // "speed", in milliseconds + if (newFrameDelay > 0) + _frameDelay = newFrameDelay; + + _fileStream->readUint16LE(); // reserved, always 0 + uint16 newWidth = _fileStream->readUint16LE(); + uint16 newHeight = _fileStream->readUint16LE(); + + if ((newWidth != 0) || (newHeight != 0)) { + if (newWidth == 0) + newWidth = _surface->w; + if (newHeight == 0) + newHeight = _surface->h; + + _surface->free(); + delete _surface; + _surface = new Graphics::Surface(); + _surface->create(newWidth, newHeight, Graphics::PixelFormat::createFormatCLUT8()); + } + + // Read subchunks + for (uint32 i = 0; i < chunkCount; ++i) { + uint32 frameSize = _fileStream->readUint32LE(); + uint16 frameType = _fileStream->readUint16LE(); + uint8 *data = new uint8[frameSize - 6]; + _fileStream->read(data, frameSize - 6); + + switch (frameType) { + case FLI_SETPAL: + unpackPalette(data); + _dirtyPalette = true; + break; + case FLI_SS2: + decodeDeltaFLC(data); + break; + case FLI_BRUN: + decodeByteRun(data); + break; + case FLI_COPY: + copyFrame(data); + break; + case PSTAMP: + /* PSTAMP - skip for now */ + break; + default: + error("FlicDecoder::decodeNextFrame(): unknown subchunk type (type = 0x%02X)", frameType); + break; + } + + delete[] data; + } +} + void FlicDecoder::FlicVideoTrack::copyDirtyRectsToBuffer(uint8 *dst, uint pitch) { for (Common::List<Common::Rect>::const_iterator it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) { for (int y = (*it).top; y < (*it).bottom; ++y) { diff --git a/video/flic_decoder.h b/video/flic_decoder.h index 1769e1ed2e..445e474b87 100644 --- a/video/flic_decoder.h +++ b/video/flic_decoder.h @@ -42,6 +42,7 @@ namespace Video { * Decoder for FLIC videos. * * Video decoder used in engines: + * - chewy * - tucker */ class FlicDecoder : public VideoDecoder { @@ -49,21 +50,23 @@ public: FlicDecoder(); virtual ~FlicDecoder(); - bool loadStream(Common::SeekableReadStream *stream); + virtual bool loadStream(Common::SeekableReadStream *stream); const Common::List<Common::Rect> *getDirtyRects() const; void clearDirtyRects(); void copyDirtyRectsToBuffer(uint8 *dst, uint pitch); -private: +protected: class FlicVideoTrack : public VideoTrack { public: - FlicVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height); + FlicVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height, bool skipHeader = false); ~FlicVideoTrack(); + virtual void readHeader(); + bool endOfTrack() const; - bool isRewindable() const { return true; } - bool rewind(); + virtual bool isRewindable() const { return true; } + virtual bool rewind(); uint16 getWidth() const; uint16 getHeight() const; @@ -71,7 +74,8 @@ private: int getCurFrame() const { return _curFrame; } int getFrameCount() const { return _frameCount; } uint32 getNextFrameStartTime() const { return _nextFrameStartTime; } - const Graphics::Surface *decodeNextFrame(); + virtual const Graphics::Surface *decodeNextFrame(); + virtual void handleFrame(); const byte *getPalette() const { _dirtyPalette = false; return _palette; } bool hasDirtyPalette() const { return _dirtyPalette; } @@ -79,7 +83,7 @@ private: void clearDirtyRects() { _dirtyRects.clear(); } void copyDirtyRectsToBuffer(uint8 *dst, uint pitch); - private: + protected: Common::SeekableReadStream *_fileStream; Graphics::Surface *_surface; |