diff options
author | Paul Gilbert | 2015-06-27 19:23:42 -0400 |
---|---|---|
committer | Paul Gilbert | 2015-06-27 19:23:42 -0400 |
commit | 7594507277ba7506b8c7142b8a1463a97036c14d (patch) | |
tree | 678a9f0e4df20423559ba5ccb38e019a38b0468d /engines/sherlock/image_file.cpp | |
parent | 7ecf553e24ce6d8267e66bb903388ff55805e418 (diff) | |
download | scummvm-rg350-7594507277ba7506b8c7142b8a1463a97036c14d.tar.gz scummvm-rg350-7594507277ba7506b8c7142b8a1463a97036c14d.tar.bz2 scummvm-rg350-7594507277ba7506b8c7142b8a1463a97036c14d.zip |
SHERLOCK: RT: Properly implement StreamingImageFile class
Diffstat (limited to 'engines/sherlock/image_file.cpp')
-rw-r--r-- | engines/sherlock/image_file.cpp | 95 |
1 files changed, 80 insertions, 15 deletions
diff --git a/engines/sherlock/image_file.cpp b/engines/sherlock/image_file.cpp index 78284e416d..4d713b155a 100644 --- a/engines/sherlock/image_file.cpp +++ b/engines/sherlock/image_file.cpp @@ -93,9 +93,10 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool } // Load data for frame and decompress it - byte *data = new byte[frame._size]; + byte *data = new byte[frame._size + 4]; stream.read(data, frame._size); - decompressFrame(frame, data); + Common::fill(data + frame._size, data + frame._size + 4, 0); + frame.decompressFrame(data, _vm->getGameID() == GType_RoseTattoo); delete[] data; push_back(frame); @@ -134,21 +135,21 @@ void ImageFile::loadPalette(Common::SeekableReadStream &stream) { } } -void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) { - frame._frame.create(frame._width, frame._height, Graphics::PixelFormat::createFormatCLUT8()); - byte *dest = (byte *)frame._frame.getPixels(); - Common::fill(dest, dest + frame._width * frame._height, 0xff); +void ImageFrame::decompressFrame(const byte *src, bool isRoseTattoo) { + _frame.create(_width, _height, Graphics::PixelFormat::createFormatCLUT8()); + byte *dest = (byte *)_frame.getPixels(); + Common::fill(dest, dest + _width * _height, 0xff); - if (frame._paletteBase) { + if (_paletteBase) { // Nibble-packed - for (uint idx = 0; idx < frame._size; ++idx, ++src) { + for (uint idx = 0; idx < _size; ++idx, ++src) { *dest++ = *src & 0xF; *dest++ = (*src >> 4); } - } else if (frame._rleEncoded && _vm->getGameID() == GType_RoseTattoo) { + } else if (_rleEncoded && isRoseTattoo) { // Rose Tattoo run length encoding doesn't use the RLE marker byte - for (int yp = 0; yp < frame._height; ++yp) { - int xSize = frame._width; + for (int yp = 0; yp < _height; ++yp) { + int xSize = _width; while (xSize > 0) { // Skip a given number of pixels byte skip = *src++; @@ -165,11 +166,11 @@ void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) { } assert(xSize == 0); } - } else if (frame._rleEncoded) { + } else if (_rleEncoded) { // RLE encoded - int frameSize = frame._width * frame._height; + int frameSize = _width * _height; while (frameSize > 0) { - if (*src == frame._rleMarker) { + if (*src == _rleMarker) { byte rleColor = src[1]; byte rleCount = src[2]; src += 3; @@ -184,7 +185,7 @@ void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) { assert(frameSize == 0); } else { // Uncompressed frame - Common::copy(src, src + frame._width * frame._height, dest); + Common::copy(src, src + _width * _height, dest); } } @@ -1007,4 +1008,68 @@ void ImageFile3DO::loadFont(Common::SeekableReadStream &stream) { delete[] widthTablePtr; } +/*----------------------------------------------------------------*/ + +StreamingImageFile::StreamingImageFile() { + _frameNumber = 0; + _stream = nullptr; + _flags = 0; + _scaleVal = 0; + _zPlacement = 0; +} + +StreamingImageFile::~StreamingImageFile() { + close(); +} + +void StreamingImageFile::load(Common::SeekableReadStream *stream, bool compressed) { + _stream = stream; + _compressed = compressed; + _frameNumber = -1; +} + +void StreamingImageFile::close() { + delete _stream; + _stream = nullptr; + _frameNumber = -1; +} + +void StreamingImageFile::getNextFrame() { + // Don't proceed if we're already at the end of the stream + if (_stream->pos() >= _stream->size()) + return; + + // Increment frame number + ++_frameNumber; + + // If necessary, decompress the next frame + Common::SeekableReadStream *frameStream = _stream; + if (_compressed) { + uint32 inSize = _stream->readUint32LE(); + Resources::decompressLZ(*_stream, _buffer, STREAMING_BUFFER_SIZE, inSize); + frameStream = new Common::MemoryReadStream(_buffer, 11, DisposeAfterUse::NO); + } + + // Load the data for the frame + _imageFrame._width = frameStream->readUint16LE() + 1; + _imageFrame._height = frameStream->readUint16LE() + 1; + _imageFrame._paletteBase = frameStream->readByte(); + _imageFrame._rleEncoded = frameStream->readByte() == 1; + _imageFrame._offset.x = frameStream->readByte(); + _imageFrame._offset.y = frameStream->readByte(); + _imageFrame._size = frameStream->readUint16LE() - 11; + _imageFrame._rleMarker = frameStream->readByte(); + + // Decode the frame + if (_compressed) { + delete frameStream; + _imageFrame.decompressFrame(_buffer + 11, true); + } else { + byte *data = new byte[_imageFrame._size]; + _stream->read(data, _imageFrame._size); + _imageFrame.decompressFrame(_buffer + 11, true); + delete[] data; + } +} + } // End of namespace Sherlock |