aboutsummaryrefslogtreecommitdiff
path: root/video/flic_decoder.cpp
diff options
context:
space:
mode:
authorFilippos Karapetis2016-10-03 00:18:39 +0300
committerFilippos Karapetis2016-10-03 00:33:49 +0300
commit7331bdc6b1f15bc9f5c8e186d4f19923c1c723a4 (patch)
tree0fc0f35c5a959e9a92f22bd99c6d0400555ff018 /video/flic_decoder.cpp
parent0152b7c47f0eef04bd01ae6e1cb808d25ccdd9a0 (diff)
downloadscummvm-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
Diffstat (limited to 'video/flic_decoder.cpp')
-rw-r--r--video/flic_decoder.cpp148
1 files changed, 76 insertions, 72 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) {