[Scummvm-git-logs] scummvm master -> 046e39428bae509f087bc0ffc25b1f925f565435

dreammaster noreply at scummvm.org
Tue Nov 30 04:16:50 UTC 2021


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
046e39428b SHERLOCK: Load frames on demand when possible


Commit: 046e39428bae509f087bc0ffc25b1f925f565435
    https://github.com/scummvm/scummvm/commit/046e39428bae509f087bc0ffc25b1f925f565435
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-11-29T20:10:46-08:00

Commit Message:
SHERLOCK: Load frames on demand when possible

This fixes bug #13101, since it no longer tries to decode
catastrophically bad frames. (Some bad frames will still be used, but
that's survivable.)

Changed paths:
    engines/sherlock/image_file.cpp
    engines/sherlock/image_file.h


diff --git a/engines/sherlock/image_file.cpp b/engines/sherlock/image_file.cpp
index 29d4cdfd4f..da2dfbf5b0 100644
--- a/engines/sherlock/image_file.cpp
+++ b/engines/sherlock/image_file.cpp
@@ -38,6 +38,7 @@ ImageFile::ImageFile() {
 }
 
 ImageFile::ImageFile(const Common::String &name, bool skipPal, bool animImages) {
+	_name = name;
 	Common::SeekableReadStream *stream = _vm->_res->load(name);
 
 	Common::fill(&_palette[0], &_palette[PALETTE_SIZE], 0);
@@ -52,8 +53,37 @@ ImageFile::ImageFile(Common::SeekableReadStream &stream, bool skipPal) {
 }
 
 ImageFile::~ImageFile() {
-	for (uint idx = 0; idx < size(); ++idx)
-		(*this)[idx]._frame.free();
+	for (uint idx = 0; idx < size(); ++idx) {
+		if (_frames[idx]._decoded)
+			_frames[idx]._frame.free();
+	}
+}
+
+ImageFrame& ImageFile::operator[](uint index) {
+	if (!_frames[index]._decoded) {
+		decodeFrame(_frames[index]);
+	}
+
+	return _frames[index];
+}
+
+uint ImageFile::size() {
+	return _frames.size();
+}
+
+void ImageFile::push_back(const ImageFrame &frame) {
+	_frames.push_back(frame);
+}
+
+void ImageFile::decodeFrame(ImageFrame &frame) {
+	Common::SeekableReadStream *stream = _vm->_res->load(_name);
+	stream->seek(frame._pos);
+	byte *data = new byte[frame._size + 4];
+	stream->read(data, frame._size);
+	Common::fill(data + frame._size, data + frame._size + 4, 0);
+	frame.decompressFrame(data, IS_ROSE_TATTOO);
+	delete[] data;
+	delete stream;
 }
 
 void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool animImages) {
@@ -92,12 +122,21 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette, bool
 			frame._size = frame._width * frame._height;
 		}
 
-		// Load data for frame and decompress it
-		byte *data1 = new byte[frame._size + 4];
-		stream.read(data1, frame._size);
-		Common::fill(data1 + frame._size, data1 + frame._size + 4, 0);
-		frame.decompressFrame(data1, IS_ROSE_TATTOO);
-		delete[] data1;
+		frame._pos = stream.pos();
+
+		if (_name.empty()) {
+			// Load data for frame and decompress it
+			frame._decoded = true;
+			byte *data1 = new byte[frame._size + 4];
+			stream.read(data1, frame._size);
+			Common::fill(data1 + frame._size, data1 + frame._size + 4, 0);
+			frame.decompressFrame(data1, IS_ROSE_TATTOO);
+			delete[] data1;
+		} else {
+			frame._decoded = false;
+
+			stream.seek(MIN(stream.pos() + frame._size, stream.size()));
+		}
 
 		push_back(frame);
 	}
@@ -302,6 +341,10 @@ ImageFile3DO::ImageFile3DO(Common::SeekableReadStream &stream, bool isRoomData)
 	}
 }
 
+void ImageFile3DO::decodeFrame(ImageFrame &frame) {
+	error("ImageFile3DO: Frame should already have been decoded");
+}
+
 void ImageFile3DO::load(Common::SeekableReadStream &stream, bool isRoomData) {
 	uint32 headerId = 0;
 
@@ -354,6 +397,7 @@ void ImageFile3DO::loadAnimationFile(Common::SeekableReadStream &stream) {
 
 		celDataSize = stream.readUint16BE();
 
+		frame._decoded = true;
 		frame._width = stream.readUint16BE() + 1; // 2 bytes BE width
 		frame._height = stream.readByte() + 1; // 1 byte BE height
 		frame._paletteBase = 0;
@@ -586,6 +630,7 @@ void ImageFile3DO::load3DOCelFile(Common::SeekableReadStream &stream) {
 			// Set up frame
 			ImageFrame imageFrame;
 
+			imageFrame._decoded = true;
 			imageFrame._width = ccbWidth;
 			imageFrame._height = ccbHeight;
 			imageFrame._paletteBase = 0;
@@ -712,6 +757,7 @@ void ImageFile3DO::load3DOCelRoomData(Common::SeekableReadStream &stream) {
 		{
 			ImageFrame imageFrame;
 
+			imageFrame._decoded = true;
 			imageFrame._width = ccbWidth;
 			imageFrame._height = ccbHeight;
 			imageFrame._paletteBase = 0;
@@ -956,6 +1002,7 @@ void ImageFile3DO::loadFont(Common::SeekableReadStream &stream) {
 		// create frame
 		ImageFrame imageFrame;
 
+		imageFrame._decoded = true;
 		imageFrame._width = widthTablePtr[curChar];
 		imageFrame._height = header_fontHeight;
 		imageFrame._paletteBase = 0;
diff --git a/engines/sherlock/image_file.h b/engines/sherlock/image_file.h
index 0ae7cc1dcb..b3dc10c13c 100644
--- a/engines/sherlock/image_file.h
+++ b/engines/sherlock/image_file.h
@@ -37,6 +37,8 @@ namespace Sherlock {
 class SherlockEngine;
 
 struct ImageFrame {
+	uint32 _pos;
+	byte _decoded;
 	uint32 _size;
 	uint16 _width, _height;
 	int _paletteBase;
@@ -76,9 +78,11 @@ struct ImageFrame {
 	int sDrawYOffset(int scaleVal) const;
 };
 
-class ImageFile : public Common::Array<ImageFrame> {
+class ImageFile {
 private:
 	static SherlockEngine *_vm;
+	Common::Array<ImageFrame> _frames;
+	Common::String _name;
 
 	/**
 	 * Load the data of the sprite
@@ -89,7 +93,13 @@ private:
 	 * Gets the palette at the start of the sprite file
 	 */
 	void loadPalette(Common::SeekableReadStream &stream);
+protected:
+	virtual void decodeFrame(ImageFrame &frame);
 public:
+	ImageFrame& operator[](uint index);
+	uint size();
+	void push_back(const ImageFrame &frame);
+
 	byte _palette[256 * 3];
 public:
 	ImageFile();
@@ -152,6 +162,9 @@ private:
 	 */
 	void loadFont(Common::SeekableReadStream &stream);
 
+protected:
+	void decodeFrame(ImageFrame &frame);
+
 public:
 	ImageFile3DO(const Common::String &name, ImageFile3DOType imageFile3DOType);
 	ImageFile3DO(Common::SeekableReadStream &stream, bool isRoomData = false);




More information about the Scummvm-git-logs mailing list