diff options
96 files changed, 341 insertions, 337 deletions
diff --git a/common/recorderfile.cpp b/common/recorderfile.cpp index 1f283715d0..7552cd45b3 100644 --- a/common/recorderfile.cpp +++ b/common/recorderfile.cpp @@ -608,7 +608,8 @@ Graphics::Surface *PlaybackFile::getScreenShot(int number) { if (screenCount == number) { screenCount++; _readStream->seek(-4, SEEK_CUR); - return Graphics::loadThumbnail(*_readStream); + Graphics::Surface *thumbnail; + return Graphics::loadThumbnail(*_readStream, thumbnail) ? thumbnail : NULL; } else { uint32 size = _readStream->readUint32BE(); _readStream->skip(size-8); diff --git a/engines/access/access.cpp b/engines/access/access.cpp index 1855280a24..c1af19026b 100644 --- a/engines/access/access.cpp +++ b/engines/access/access.cpp @@ -488,11 +488,6 @@ Common::Error AccessEngine::loadGameState(int slot) { if (!readSavegameHeader(saveFile, header)) error("Invalid savegame"); - if (header._thumbnail) { - header._thumbnail->free(); - delete header._thumbnail; - } - // Load most of the savegame data synchronize(s); delete saveFile; @@ -537,9 +532,8 @@ void AccessEngine::synchronize(Common::Serializer &s) { const char *const SAVEGAME_STR = "ACCESS"; #define SAVEGAME_STR_SIZE 6 -bool AccessEngine::readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &header) { +WARN_UNUSED_RESULT bool AccessEngine::readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &header, bool skipThumbnail) { char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; - header._thumbnail = nullptr; // Validate the header Id in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1); @@ -557,9 +551,9 @@ bool AccessEngine::readSavegameHeader(Common::InSaveFile *in, AccessSavegameHead header._saveName += ch; // Get the thumbnail - header._thumbnail = Graphics::loadThumbnail(*in); - if (!header._thumbnail) + if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) { return false; + } // Read in save date/time header._year = in->readSint16LE(); diff --git a/engines/access/access.h b/engines/access/access.h index 972dd4c380..56646f01c9 100644 --- a/engines/access/access.h +++ b/engines/access/access.h @@ -306,7 +306,7 @@ public: /** * Read in a savegame header */ - static bool readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &header); + WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &header, bool skipThumbnail = true); /** * Write out a savegame header diff --git a/engines/access/detection.cpp b/engines/access/detection.cpp index 3e70de3635..186fcbdf06 100644 --- a/engines/access/detection.cpp +++ b/engines/access/detection.cpp @@ -157,11 +157,9 @@ SaveStateList AccessMetaEngine::listSaves(const char *target) const { Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); if (in) { - Access::AccessEngine::readSavegameHeader(in, header); - saveList.push_back(SaveStateDescriptor(slot, header._saveName)); + if (Access::AccessEngine::readSavegameHeader(in, header)) + saveList.push_back(SaveStateDescriptor(slot, header._saveName)); - header._thumbnail->free(); - delete header._thumbnail; delete in; } } @@ -187,7 +185,11 @@ SaveStateDescriptor AccessMetaEngine::querySaveMetaInfos(const char *target, int if (f) { Access::AccessSavegameHeader header; - Access::AccessEngine::readSavegameHeader(f, header); + if (!Access::AccessEngine::readSavegameHeader(f, header, false)) { + delete f; + return SaveStateDescriptor(); + } + delete f; // Create the return descriptor diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp index e63beb2c07..ab634bc02a 100644 --- a/engines/adl/detection.cpp +++ b/engines/adl/detection.cpp @@ -401,7 +401,11 @@ SaveStateDescriptor AdlMetaEngine::querySaveMetaInfos(const char *target, int sl return SaveStateDescriptor(); } - Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*inFile); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*inFile, thumbnail)) { + delete inFile; + return SaveStateDescriptor(); + } sd.setThumbnail(thumbnail); delete inFile; diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp index e26f5c84fc..817be08f2c 100644 --- a/engines/agi/detection.cpp +++ b/engines/agi/detection.cpp @@ -375,7 +375,11 @@ SaveStateDescriptor AgiMetaEngine::querySaveMetaInfos(const char *target, int sl char saveVersion = in->readByte(); if (saveVersion >= 4) { - Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*in, thumbnail)) { + delete in; + return SaveStateDescriptor(); + } descriptor.setThumbnail(thumbnail); diff --git a/engines/avalanche/detection.cpp b/engines/avalanche/detection.cpp index def395b77f..64634dc017 100644 --- a/engines/avalanche/detection.cpp +++ b/engines/avalanche/detection.cpp @@ -193,7 +193,12 @@ SaveStateDescriptor AvalancheMetaEngine::querySaveMetaInfos(const char *target, SaveStateDescriptor desc(slot, description); - Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*f); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*f, thumbnail)) { + warning("Cannot read thumbnail data, possibly broken savegame"); + delete f; + return SaveStateDescriptor(); + } desc.setThumbnail(thumbnail); delete f; diff --git a/engines/bbvs/bbvs.h b/engines/bbvs/bbvs.h index 9fb6b9cac3..a9d37c2551 100644 --- a/engines/bbvs/bbvs.h +++ b/engines/bbvs/bbvs.h @@ -417,7 +417,7 @@ public: const char *getSavegameFilename(int num); bool existsSavegame(int num); static Common::String getSavegameFilename(const Common::String &target, int num); - static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header); + WARN_UNUSED_RESULT static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail = true); void allocSnapshot(); void freeSnapshot(); diff --git a/engines/bbvs/detection.cpp b/engines/bbvs/detection.cpp index 1b2c644dda..b30c6d3f2d 100644 --- a/engines/bbvs/detection.cpp +++ b/engines/bbvs/detection.cpp @@ -124,7 +124,7 @@ SaveStateList BbvsMetaEngine::listSaves(const char *target) const { if (slotNum >= 0 && slotNum <= 999) { Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str()); if (in) { - if (Bbvs::BbvsEngine::readSaveHeader(in, false, header) == Bbvs::BbvsEngine::kRSHENoError) { + if (Bbvs::BbvsEngine::readSaveHeader(in, header) == Bbvs::BbvsEngine::kRSHENoError) { saveList.push_back(SaveStateDescriptor(slotNum, header.description)); } delete in; @@ -142,7 +142,7 @@ SaveStateDescriptor BbvsMetaEngine::querySaveMetaInfos(const char *target, int s if (in) { Bbvs::BbvsEngine::SaveHeader header; Bbvs::BbvsEngine::kReadSaveHeaderError error; - error = Bbvs::BbvsEngine::readSaveHeader(in, true, header); + error = Bbvs::BbvsEngine::readSaveHeader(in, header, false); delete in; if (error == Bbvs::BbvsEngine::kRSHENoError) { SaveStateDescriptor desc(slot, header.description); diff --git a/engines/bbvs/saveload.cpp b/engines/bbvs/saveload.cpp index 74c255c860..d4782aad39 100644 --- a/engines/bbvs/saveload.cpp +++ b/engines/bbvs/saveload.cpp @@ -27,7 +27,7 @@ namespace Bbvs { -BbvsEngine::kReadSaveHeaderError BbvsEngine::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) { +WARN_UNUSED_RESULT BbvsEngine::kReadSaveHeaderError BbvsEngine::readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail) { header.version = in->readUint32LE(); if (header.version > BBVS_SAVEGAME_VERSION) @@ -38,10 +38,8 @@ BbvsEngine::kReadSaveHeaderError BbvsEngine::readSaveHeader(Common::SeekableRead while (descriptionLen--) header.description += (char)in->readByte(); - if (loadThumbnail) { - header.thumbnail = Graphics::loadThumbnail(*in); - } else { - Graphics::skipThumbnail(*in); + if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) { + return kRSHEIoError; } // Not used yet, reserved for future usage @@ -101,7 +99,7 @@ void BbvsEngine::loadgame(const char *filename) { SaveHeader header; - kReadSaveHeaderError errorCode = readSaveHeader(in, false, header); + kReadSaveHeaderError errorCode = readSaveHeader(in, header); if (errorCode != kRSHENoError) { warning("Error loading savegame '%s'", filename); diff --git a/engines/cge/cge.h b/engines/cge/cge.h index d3f8a93c1d..668224d2f7 100644 --- a/engines/cge/cge.h +++ b/engines/cge/cge.h @@ -246,7 +246,7 @@ public: void mainLoop(); void handleFrame(); void saveGame(int slotNumber, const Common::String &desc); - static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header); + WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail = true); void switchMusic(); void selectPocket(int n); void expandSprite(Sprite *spr); diff --git a/engines/cge/cge_main.cpp b/engines/cge/cge_main.cpp index b60f201cb0..fcbbf34a4d 100644 --- a/engines/cge/cge_main.cpp +++ b/engines/cge/cge_main.cpp @@ -242,10 +242,6 @@ bool CGEEngine::loadGame(int slotNumber, SavegameHeader *header, bool tiny) { delete readStream; return true; } - - // Delete the thumbnail - saveHeader.thumbnail->free(); - delete saveHeader.thumbnail; } // Get in the savegame @@ -424,9 +420,7 @@ void CGEEngine::syncGame(Common::SeekableReadStream *readStream, Common::WriteSt } } -bool CGEEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) { - header.thumbnail = nullptr; - +WARN_UNUSED_RESULT bool CGEEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail) { // Get the savegame version header.version = in->readByte(); if (header.version > kSavegameVersion) @@ -439,9 +433,9 @@ bool CGEEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &heade header.saveName += ch; // Get the thumbnail - header.thumbnail = Graphics::loadThumbnail(*in); - if (!header.thumbnail) + if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) { return false; + } // Read in save date/time header.saveYear = in->readSint16LE(); diff --git a/engines/cge/detection.cpp b/engines/cge/detection.cpp index 482591bf50..cae2e036b9 100644 --- a/engines/cge/detection.cpp +++ b/engines/cge/detection.cpp @@ -221,10 +221,6 @@ SaveStateList CGEMetaEngine::listSaves(const char *target) const { // Valid savegame if (CGE::CGEEngine::readSavegameHeader(file, header)) { saveList.push_back(SaveStateDescriptor(slotNum, header.saveName)); - if (header.thumbnail) { - header.thumbnail->free(); - delete header.thumbnail; - } } } else { // Must be an original format savegame @@ -253,7 +249,7 @@ SaveStateDescriptor CGEMetaEngine::querySaveMetaInfos(const char *target, int sl f->read(buffer, kSavegameStrSize + 1); bool hasHeader = !strncmp(buffer, CGE::savegameStr, kSavegameStrSize + 1) && - CGE::CGEEngine::readSavegameHeader(f, header); + CGE::CGEEngine::readSavegameHeader(f, header, false); delete f; if (!hasHeader) { diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h index 18f919b5eb..899520c6dd 100644 --- a/engines/cge2/cge2.h +++ b/engines/cge2/cge2.h @@ -161,7 +161,7 @@ public: virtual Common::Error loadGameState(int slot); virtual Common::Error run(); - static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header); + WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail = true); GUI::Debugger *getDebugger() { return _console; diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp index d05dfffedc..68f16d8dc9 100644 --- a/engines/cge2/detection.cpp +++ b/engines/cge2/detection.cpp @@ -221,10 +221,6 @@ SaveStateList CGE2MetaEngine::listSaves(const char *target) const { // Valid savegame if (CGE2::CGE2Engine::readSavegameHeader(file, header)) { saveList.push_back(SaveStateDescriptor(slotNum, header.saveName)); - if (header.thumbnail) { - header.thumbnail->free(); - delete header.thumbnail; - } } } else { // Must be an original format savegame @@ -253,7 +249,7 @@ SaveStateDescriptor CGE2MetaEngine::querySaveMetaInfos(const char *target, int s f->read(buffer, kSavegameStrSize + 1); bool hasHeader = !strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) && - CGE2::CGE2Engine::readSavegameHeader(f, header); + CGE2::CGE2Engine::readSavegameHeader(f, header, false); delete f; if (!hasHeader) { diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp index cd0be84567..83cba5316d 100644 --- a/engines/cge2/saveload.cpp +++ b/engines/cge2/saveload.cpp @@ -117,10 +117,6 @@ bool CGE2Engine::loadGame(int slotNumber) { delete readStream; return false; } - - // Delete the thumbnail - saveHeader.thumbnail->free(); - delete saveHeader.thumbnail; } resetGame(); @@ -180,9 +176,7 @@ void CGE2Engine::writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &h out->writeSint16LE(td.tm_min); } -bool CGE2Engine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) { - header.thumbnail = nullptr; - +WARN_UNUSED_RESULT bool CGE2Engine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail) { // Get the savegame version header.version = in->readByte(); if (header.version > kSavegameVersion) @@ -195,9 +189,9 @@ bool CGE2Engine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &head header.saveName += ch; // Get the thumbnail - header.thumbnail = Graphics::loadThumbnail(*in); - if (!header.thumbnail) + if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) { return false; + } // Read in save date/time header.saveYear = in->readSint16LE(); diff --git a/engines/cruise/detection.cpp b/engines/cruise/detection.cpp index 6f5d236173..3dfd414fd2 100644 --- a/engines/cruise/detection.cpp +++ b/engines/cruise/detection.cpp @@ -241,9 +241,8 @@ SaveStateList CruiseMetaEngine::listSaves(const char *target) const { Common::InSaveFile *in = saveFileMan->openForLoading(*file); if (in) { Cruise::CruiseSavegameHeader header; - Cruise::readSavegameHeader(in, header); - saveList.push_back(SaveStateDescriptor(slotNum, header.saveName)); - delete header.thumbnail; + if (Cruise::readSavegameHeader(in, header)) + saveList.push_back(SaveStateDescriptor(slotNum, header.saveName)); delete in; } } @@ -264,7 +263,11 @@ SaveStateDescriptor CruiseMetaEngine::querySaveMetaInfos(const char *target, int if (f) { Cruise::CruiseSavegameHeader header; - Cruise::readSavegameHeader(f, header); + if (!Cruise::readSavegameHeader(f, header, false)) { + delete f; + return SaveStateDescriptor(); + } + delete f; // Create the return descriptor diff --git a/engines/cruise/saveload.cpp b/engines/cruise/saveload.cpp index a62648df08..7aaeb06905 100644 --- a/engines/cruise/saveload.cpp +++ b/engines/cruise/saveload.cpp @@ -43,9 +43,8 @@ struct overlayRestoreTemporary { overlayRestoreTemporary ovlRestoreData[90]; -bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header) { +WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header, bool skipThumbnail) { char saveIdentBuffer[6]; - header.thumbnail = NULL; // Validate the header Id in->read(saveIdentBuffer, 6); @@ -62,9 +61,9 @@ bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header) { while ((ch = (char)in->readByte()) != '\0') header.saveName += ch; // Get the thumbnail - header.thumbnail = Graphics::loadThumbnail(*in); - if (!header.thumbnail) + if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) { return false; + } return true; } @@ -827,8 +826,10 @@ Common::Error loadSavegameData(int saveGameIdx) { // Skip over the savegame header CruiseSavegameHeader header; - readSavegameHeader(f, header); - delete header.thumbnail; + if (!readSavegameHeader(f, header)) { + delete f; + return Common::kReadingFailed; + } // Synchronise the remaining data of the savegame Common::Serializer s(f, NULL); diff --git a/engines/cruise/saveload.h b/engines/cruise/saveload.h index 6fb1f4b545..c92f0e9da5 100644 --- a/engines/cruise/saveload.h +++ b/engines/cruise/saveload.h @@ -38,7 +38,7 @@ struct CruiseSavegameHeader { Common::Error saveSavegameData(int saveGameIdx, const Common::String &saveName); Common::Error loadSavegameData(int saveGameIdx); -bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header); +WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header, bool skipThumbnail = true); void initVars(); } // End of namespace Cruise diff --git a/engines/dm/dm.h b/engines/dm/dm.h index 16307778ba..e330cb6be7 100644 --- a/engines/dm/dm.h +++ b/engines/dm/dm.h @@ -332,7 +332,7 @@ public: Thing _thingParty; // @ C0xFFFF_THING_PARTY }; -bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header); +WARN_UNUSED_RESULT bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header, bool skipThumbnail = true); } // End of namespace DM diff --git a/engines/dm/loadsave.cpp b/engines/dm/loadsave.cpp index 3d8f76c33f..864a726367 100644 --- a/engines/dm/loadsave.cpp +++ b/engines/dm/loadsave.cpp @@ -70,7 +70,10 @@ LoadgameResult DMEngine::loadgame(int16 slot) { file = saveFileManager->openForLoading(fileName); SaveGameHeader header; - readSaveGameHeader(file, &header); + if (!readSaveGameHeader(file, &header)) { + delete file; + return kDMLoadgameFailure; + } warning("MISSING CODE: missing check for matching format and platform in save in f435_loadgame"); @@ -397,7 +400,7 @@ bool DMEngine::writeCompleteSaveFile(int16 saveSlot, Common::String& saveDescrip return true; } -bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header) { +WARN_UNUSED_RESULT bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header, bool skipThumbnail) { uint32 id = in->readUint32BE(); // Check if it's a valid ScummVM savegame @@ -419,7 +422,11 @@ bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header) { header->_descr.setDescription(saveName); // Get the thumbnail - header->_descr.setThumbnail(Graphics::loadThumbnail(*in)); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*in, thumbnail, skipThumbnail)) { + return false; + } + header->_descr.setThumbnail(thumbnail); uint32 saveDate = in->readUint32BE(); uint16 saveTime = in->readUint16BE(); diff --git a/engines/draci/detection.cpp b/engines/draci/detection.cpp index 65427bd8cd..9a76e3890c 100644 --- a/engines/draci/detection.cpp +++ b/engines/draci/detection.cpp @@ -132,10 +132,6 @@ SaveStateList DraciMetaEngine::listSaves(const char *target) const { Draci::DraciSavegameHeader header; if (Draci::readSavegameHeader(in, header)) { saveList.push_back(SaveStateDescriptor(slotNum, header.saveName)); - if (header.thumbnail) { - header.thumbnail->free(); - delete header.thumbnail; - } } delete in; } @@ -157,7 +153,11 @@ SaveStateDescriptor DraciMetaEngine::querySaveMetaInfos(const char *target, int if (f) { Draci::DraciSavegameHeader header; - Draci::readSavegameHeader(f, header); + if (!Draci::readSavegameHeader(f, header, false)) { + delete f; + return SaveStateDescriptor(); + } + delete f; // Create the return descriptor diff --git a/engines/draci/saveload.cpp b/engines/draci/saveload.cpp index 3e7f8651c1..e30af5375e 100644 --- a/engines/draci/saveload.cpp +++ b/engines/draci/saveload.cpp @@ -35,9 +35,8 @@ namespace Draci { static const char *const draciIdentString = "DRACI"; -bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header) { +WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header, bool skipThumbnail) { char saveIdentBuffer[6]; - header.thumbnail = NULL; // Validate the header Id in->read(saveIdentBuffer, 6); @@ -59,9 +58,9 @@ bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header) { header.playtime = in->readUint32LE(); // Get the thumbnail - header.thumbnail = Graphics::loadThumbnail(*in); - if (!header.thumbnail) + if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) { return false; + } return true; } @@ -130,10 +129,6 @@ Common::Error loadSavegameData(int saveGameIdx, DraciEngine *vm) { if (!readSavegameHeader(f, header)) { return Common::kNoGameDataFoundError; } - if (header.thumbnail) { - header.thumbnail->free(); - delete header.thumbnail; - } // Pre-processing vm->_game->rememberRoomNumAsPrevious(); diff --git a/engines/draci/saveload.h b/engines/draci/saveload.h index 6f951a3409..bceaebb468 100644 --- a/engines/draci/saveload.h +++ b/engines/draci/saveload.h @@ -42,7 +42,7 @@ struct DraciSavegameHeader { class DraciEngine; -bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header); +WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header, bool skipThumbnail = true); void writeSavegameHeader(Common::OutSaveFile *out, const DraciSavegameHeader &header); Common::Error saveSavegameData(int saveGameIdx, const Common::String &saveName, DraciEngine &vm); Common::Error loadSavegameData(int saveGameIdx, DraciEngine *vm); diff --git a/engines/drascula/detection.cpp b/engines/drascula/detection.cpp index 5f453839e7..a1f2f3e117 100644 --- a/engines/drascula/detection.cpp +++ b/engines/drascula/detection.cpp @@ -430,7 +430,11 @@ SaveStateDescriptor DrasculaMetaEngine::querySaveMetaInfos(const char *target, i return SaveStateDescriptor(); } - Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*in, thumbnail)) { + delete in; + return SaveStateDescriptor(); + } desc.setThumbnail(thumbnail); delete in; diff --git a/engines/dreamweb/detection.cpp b/engines/dreamweb/detection.cpp index 11966047b0..36af0c3811 100644 --- a/engines/dreamweb/detection.cpp +++ b/engines/dreamweb/detection.cpp @@ -198,7 +198,12 @@ SaveStateDescriptor DreamWebMetaEngine::querySaveMetaInfos(const char *target, i uint32 saveDate = in->readUint32LE(); uint32 saveTime = in->readUint32LE(); uint32 playTime = in->readUint32LE(); - Graphics::Surface *thumbnail = Graphics::loadThumbnail(*in); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*in, thumbnail)) { + warning("Missing or broken thumbnail - skipping"); + delete in; + return desc; + } int day = (saveDate >> 24) & 0xFF; int month = (saveDate >> 16) & 0xFF; diff --git a/engines/fullpipe/detection.cpp b/engines/fullpipe/detection.cpp index 9dd1d6beb4..3144a0ebff 100644 --- a/engines/fullpipe/detection.cpp +++ b/engines/fullpipe/detection.cpp @@ -184,7 +184,9 @@ SaveStateList FullpipeMetaEngine::listSaves(const char *target) const { Common::ScopedPtr<Common::InSaveFile> in(saveFileMan->openForLoading(*file)); if (in) { Fullpipe::FullpipeSavegameHeader header; - Fullpipe::readSavegameHeader(in.get(), header); + if (!Fullpipe::readSavegameHeader(in.get(), header)) { + continue; + } SaveStateDescriptor desc; @@ -212,7 +214,9 @@ SaveStateDescriptor FullpipeMetaEngine::querySaveMetaInfos(const char *target, i if (f) { Fullpipe::FullpipeSavegameHeader header; - Fullpipe::readSavegameHeader(f.get(), header); + if (!Fullpipe::readSavegameHeader(f.get(), header, false)) { + return SaveStateDescriptor(); + } // Create the return descriptor SaveStateDescriptor desc; diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h index 03c3093086..eb5957c78e 100644 --- a/engines/fullpipe/gameloader.h +++ b/engines/fullpipe/gameloader.h @@ -84,7 +84,7 @@ struct FullpipeSavegameHeader { uint32 date; uint16 time; uint32 playtime; - Common::SharedPtr<Graphics::Surface> thumbnail; + Graphics::Surface *thumbnail; }; struct SaveHeader { @@ -142,7 +142,7 @@ class GameLoader : public CObject { }; const char *getSavegameFile(int saveGameIdx); -bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header); +WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header, bool skipThumbnail = true); void parseSavegameHeader(Fullpipe::FullpipeSavegameHeader &header, SaveStateDescriptor &desc); Inventory2 *getGameLoaderInventory(); diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp index be1e73ff70..45ccabc7d5 100644 --- a/engines/fullpipe/modal.cpp +++ b/engines/fullpipe/modal.cpp @@ -2142,7 +2142,8 @@ bool ModalSaveGame::getFileInfo(int slot, FileInfo *fileinfo) { return false; Fullpipe::FullpipeSavegameHeader header; - Fullpipe::readSavegameHeader(f.get(), header); + if (!Fullpipe::readSavegameHeader(f.get(), header)) + return false; // Create the return descriptor SaveStateDescriptor desc(slot, header.saveName); diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp index 9d4d5ab09a..250c527f40 100644 --- a/engines/fullpipe/stateloader.cpp +++ b/engines/fullpipe/stateloader.cpp @@ -193,7 +193,7 @@ void fillDummyHeader(Fullpipe::FullpipeSavegameHeader &header) { header.playtime = 0; } -bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header) { +WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header, bool skipThumbnail) { uint oldPos = in->pos(); in->seek(-4, SEEK_END); @@ -237,13 +237,13 @@ bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header) header.description = header.saveName; // Get the thumbnail - header.thumbnail = Common::SharedPtr<Graphics::Surface>(Graphics::loadThumbnail(*in), Graphics::SurfaceDeleter()); + if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) { + in->seek(oldPos, SEEK_SET); // Rewind the file + return false; + } in->seek(oldPos, SEEK_SET); // Rewind the file - if (!header.thumbnail) - return false; - return true; } diff --git a/engines/gnap/detection.cpp b/engines/gnap/detection.cpp index d19d420ff8..97c9128002 100644 --- a/engines/gnap/detection.cpp +++ b/engines/gnap/detection.cpp @@ -141,13 +141,8 @@ SaveStateList GnapMetaEngine::listSaves(const char *target) const { Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); if (in) { - Gnap::GnapEngine::readSavegameHeader(in, header); - saveList.push_back(SaveStateDescriptor(slot, header._saveName)); - - if (header._thumbnail) { - header._thumbnail->free(); - delete header._thumbnail; - } + if (Gnap::GnapEngine::readSavegameHeader(in, header)) + saveList.push_back(SaveStateDescriptor(slot, header._saveName)); delete in; } } @@ -179,7 +174,11 @@ SaveStateDescriptor GnapMetaEngine::querySaveMetaInfos(const char *target, int s SaveStateDescriptor desc(slot, saveName); if (version != 1) { - Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*file); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*file, thumbnail)) { + delete file; + return SaveStateDescriptor(); + } desc.setThumbnail(thumbnail); } diff --git a/engines/gnap/gnap.h b/engines/gnap/gnap.h index dbefa31795..dd653304e7 100644 --- a/engines/gnap/gnap.h +++ b/engines/gnap/gnap.h @@ -319,7 +319,7 @@ public: Common::String generateSaveName(int slot); void synchronize(Common::Serializer &s); void writeSavegameHeader(Common::OutSaveFile *out, GnapSavegameHeader &header); - static bool readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &header); + WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &header, bool skipThumbnail = true); void delayTicks(int val, int idx, bool updateCursor); void delayTicksA(int val, int idx); diff --git a/engines/gnap/menu.cpp b/engines/gnap/menu.cpp index 9606273b4c..34b5f18473 100644 --- a/engines/gnap/menu.cpp +++ b/engines/gnap/menu.cpp @@ -589,9 +589,8 @@ void GnapEngine::writeSavegameHeader(Common::OutSaveFile *out, GnapSavegameHeade out->writeSint16LE(td.tm_min); } -bool GnapEngine::readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &header) { +WARN_UNUSED_RESULT bool GnapEngine::readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &header, bool skipThumbnail) { char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; - header._thumbnail = nullptr; // Validate the header Id in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1); @@ -612,9 +611,9 @@ bool GnapEngine::readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader & if (header._version == 1) header._thumbnail = nullptr; else { - header._thumbnail = Graphics::loadThumbnail(*in); - if (!header._thumbnail) + if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) { return false; + } } // Read in save date/time diff --git a/engines/hopkins/detection.cpp b/engines/hopkins/detection.cpp index 041afecaa8..ebefee6278 100644 --- a/engines/hopkins/detection.cpp +++ b/engines/hopkins/detection.cpp @@ -168,9 +168,6 @@ SaveStateList HopkinsMetaEngine::listSaves(const char *target) const { if (in) { if (Hopkins::SaveLoadManager::readSavegameHeader(in, header)) { saveList.push_back(SaveStateDescriptor(slot, header._saveName)); - - header._thumbnail->free(); - delete header._thumbnail; } delete in; @@ -198,7 +195,11 @@ SaveStateDescriptor HopkinsMetaEngine::querySaveMetaInfos(const char *target, in if (f) { Hopkins::hopkinsSavegameHeader header; - Hopkins::SaveLoadManager::readSavegameHeader(f, header); + if (!Hopkins::SaveLoadManager::readSavegameHeader(f, header, false)) { + delete f; + return SaveStateDescriptor(); + } + delete f; // Create the return descriptor diff --git a/engines/hopkins/dialogs.cpp b/engines/hopkins/dialogs.cpp index fc613f892d..b8f1c73304 100644 --- a/engines/hopkins/dialogs.cpp +++ b/engines/hopkins/dialogs.cpp @@ -692,7 +692,7 @@ void DialogsManager::showSaveLoad(SaveLoadMode mode) { for (int slotNumber = 1; slotNumber <= 6; ++slotNumber) { hopkinsSavegameHeader header; - if (_vm->_saveLoad->readSavegameHeader(slotNumber, header)) { + if (_vm->_saveLoad->readSavegameHeader(slotNumber, header, false)) { Graphics::Surface thumb8; _vm->_saveLoad->convertThumb16To8(header._thumbnail, &thumb8); diff --git a/engines/hopkins/saveload.cpp b/engines/hopkins/saveload.cpp index 05c7fb8119..35a80458ff 100644 --- a/engines/hopkins/saveload.cpp +++ b/engines/hopkins/saveload.cpp @@ -77,9 +77,8 @@ void SaveLoadManager::load(const Common::String &file, byte *buf) { delete savefile; } -bool SaveLoadManager::readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header) { +WARN_UNUSED_RESULT bool SaveLoadManager::readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header, bool skipThumbnail) { char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; - header._thumbnail = NULL; // Validate the header Id in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1); @@ -96,9 +95,9 @@ bool SaveLoadManager::readSavegameHeader(Common::InSaveFile *in, hopkinsSavegame while ((ch = (char)in->readByte()) != '\0') header._saveName += ch; // Get the thumbnail - header._thumbnail = Graphics::loadThumbnail(*in); - if (!header._thumbnail) + if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) { return false; + } // Read in save date/time header._year = in->readSint16LE(); @@ -186,10 +185,10 @@ Common::Error SaveLoadManager::loadGame(int slot) { // Read in the savegame header hopkinsSavegameHeader header; - readSavegameHeader(savefile, header); - if (header._thumbnail) - header._thumbnail->free(); - delete header._thumbnail; + if (!readSavegameHeader(savefile, header)) { + delete savefile; + return Common::kReadingFailed; + } // Read in the savegame data syncSavegameData(serializer, header._version); @@ -212,14 +211,14 @@ Common::Error SaveLoadManager::loadGame(int slot) { return Common::kNoError; } -bool SaveLoadManager::readSavegameHeader(int slot, hopkinsSavegameHeader &header) { +WARN_UNUSED_RESULT bool SaveLoadManager::readSavegameHeader(int slot, hopkinsSavegameHeader &header, bool skipThumbnail) { // Try and open the save file for reading Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading( _vm->generateSaveName(slot)); if (!savefile) return false; - bool result = readSavegameHeader(savefile, header); + bool result = readSavegameHeader(savefile, header, skipThumbnail); delete savefile; return result; } diff --git a/engines/hopkins/saveload.h b/engines/hopkins/saveload.h index 7b4ec307f5..33234f49fa 100644 --- a/engines/hopkins/saveload.h +++ b/engines/hopkins/saveload.h @@ -61,9 +61,9 @@ public: bool saveFile(const Common::String &file, const void *buf, size_t n); void load(const Common::String &file, byte *buf); - static bool readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header); + WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header, bool skipThumbnail = true); void writeSavegameHeader(Common::OutSaveFile *out, hopkinsSavegameHeader &header); - bool readSavegameHeader(int slot, hopkinsSavegameHeader &header); + WARN_UNUSED_RESULT bool readSavegameHeader(int slot, hopkinsSavegameHeader &header, bool skipThumbnail = true); Common::Error saveGame(int slot, const Common::String &saveName); Common::Error loadGame(int slot); diff --git a/engines/hugo/detection.cpp b/engines/hugo/detection.cpp index 4e4746c002..6d2fec5421 100644 --- a/engines/hugo/detection.cpp +++ b/engines/hugo/detection.cpp @@ -241,7 +241,12 @@ SaveStateDescriptor HugoMetaEngine::querySaveMetaInfos(const char *target, int s SaveStateDescriptor desc(slot, saveName); - Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*file); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*file, thumbnail)) { + warning("Missing or broken savegame thumbnail"); + delete file; + return SaveStateDescriptor(); + } desc.setThumbnail(thumbnail); uint32 saveDate = file->readUint32BE(); diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp index 70c7e7c93c..79e1d9f494 100644 --- a/engines/kyra/detection.cpp +++ b/engines/kyra/detection.cpp @@ -256,7 +256,7 @@ SaveStateList KyraMetaEngine::listSaves(const char *target) const { if (slotNum >= 0 && slotNum <= 999) { Common::InSaveFile *in = saveFileMan->openForLoading(*file); if (in) { - if (Kyra::KyraEngine_v1::readSaveHeader(in, false, header) == Kyra::KyraEngine_v1::kRSHENoError) { + if (Kyra::KyraEngine_v1::readSaveHeader(in, header) == Kyra::KyraEngine_v1::kRSHENoError) { // WORKAROUND: Old savegames are using 'German' as description for kyra3 restart game save (slot 0), // since that looks odd we replace it by "New Game". if (slotNum == 0 && header.gameID == Kyra::GI_KYRA3) @@ -298,7 +298,7 @@ SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int s Kyra::KyraEngine_v1::SaveHeader header; Kyra::KyraEngine_v1::ReadSaveHeaderError error; - error = Kyra::KyraEngine_v1::readSaveHeader(in, true, header); + error = Kyra::KyraEngine_v1::readSaveHeader(in, header, false); delete in; if (error == Kyra::KyraEngine_v1::kRSHENoError) { diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h index 4de7494510..bbbd59a4b8 100644 --- a/engines/kyra/kyra_v1.h +++ b/engines/kyra/kyra_v1.h @@ -416,7 +416,7 @@ protected: kRSHEIoError = 3 }; - static ReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *file, bool loadThumbnail, SaveHeader &header); + WARN_UNUSED_RESULT static ReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *file, SaveHeader &header, bool skipThumbnail = true); void loadGameStateCheck(int slot); virtual Common::Error loadGameState(int slot) = 0; diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp index b44850f5c9..c306d6cb5d 100644 --- a/engines/kyra/saveload.cpp +++ b/engines/kyra/saveload.cpp @@ -37,12 +37,11 @@ namespace Kyra { -KyraEngine_v1::ReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) { +WARN_UNUSED_RESULT KyraEngine_v1::ReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail) { uint32 type = in->readUint32BE(); header.originalSave = false; header.oldHeader = false; header.flags = 0; - header.thumbnail = 0; if (type == MKTAG('K', 'Y', 'R', 'A') || type == MKTAG('A', 'R', 'Y', 'K')) { // old Kyra1 header ID header.gameID = GI_KYRA1; @@ -125,10 +124,8 @@ KyraEngine_v1::ReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekabl header.flags = in->readUint32BE(); if (header.version >= 14) { - if (loadThumbnail) { - header.thumbnail = Graphics::loadThumbnail(*in); - } else { - Graphics::skipThumbnail(*in); + if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) { + return kRSHEIoError; } } @@ -140,7 +137,7 @@ Common::SeekableReadStream *KyraEngine_v1::openSaveForReading(const char *filena if (!(in = _saveFileMan->openForLoading(filename))) return 0; - ReadSaveHeaderError errorCode = KyraEngine_v1::readSaveHeader(in, false, header); + ReadSaveHeaderError errorCode = KyraEngine_v1::readSaveHeader(in, header); if (errorCode != kRSHENoError) { if (errorCode == kRSHEInvalidType) warning("No ScummVM Kyra engine savefile header"); diff --git a/engines/lab/lab.h b/engines/lab/lab.h index 2a1e527098..aedf0181ec 100644 --- a/engines/lab/lab.h +++ b/engines/lab/lab.h @@ -502,7 +502,7 @@ private: void handleTrialWarning(); }; -bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header); +WARN_UNUSED_RESULT bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header, bool skipThumbnail = true); } // End of namespace Lab diff --git a/engines/lab/savegame.cpp b/engines/lab/savegame.cpp index 656595e3e5..46ef1486f0 100644 --- a/engines/lab/savegame.cpp +++ b/engines/lab/savegame.cpp @@ -76,7 +76,7 @@ void LabEngine::writeSaveGameHeader(Common::OutSaveFile *out, const Common::Stri out->writeUint32BE(playTime); } -bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) { +WARN_UNUSED_RESULT bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header, bool skipThumbnail) { uint32 id = in->readUint32BE(); // Check if it's a valid ScummVM savegame @@ -98,7 +98,11 @@ bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) { header._descr.setDescription(saveName); // Get the thumbnail - header._descr.setThumbnail(Graphics::loadThumbnail(*in)); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*in, thumbnail, skipThumbnail)) { + return false; + } + header._descr.setThumbnail(thumbnail); uint32 saveDate = in->readUint32BE(); uint16 saveTime = in->readUint16BE(); @@ -174,7 +178,11 @@ bool LabEngine::loadGame(int slot) { return false; SaveGameHeader header; - readSaveGameHeader(file, header); + if (!readSaveGameHeader(file, header)) { + delete file; + return false; + } + _roomNum = file->readUint16LE(); _music->checkRoomMusic(1, _roomNum); _direction = file->readUint16LE(); diff --git a/engines/lilliput/detection.cpp b/engines/lilliput/detection.cpp index a09e5f05de..466c89e362 100644 --- a/engines/lilliput/detection.cpp +++ b/engines/lilliput/detection.cpp @@ -233,7 +233,11 @@ SaveStateDescriptor LilliputMetaEngine::querySaveMetaInfos(const char *target, i SaveStateDescriptor desc(slot, saveName); - Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*file); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*file, thumbnail)) { + delete file; + return SaveStateDescriptor(); + } desc.setThumbnail(thumbnail); desc.setDeletableFlag(true); diff --git a/engines/macventure/detection.cpp b/engines/macventure/detection.cpp index c179647121..5eda420cb2 100644 --- a/engines/macventure/detection.cpp +++ b/engines/macventure/detection.cpp @@ -54,7 +54,7 @@ static const PlainGameDescriptor macventureGames[] = { namespace MacVenture { -SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot); +SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot, bool skipThumbnail = true); class MacVentureMetaEngine : public AdvancedMetaEngine { public: @@ -164,7 +164,7 @@ SaveStateDescriptor MacVentureMetaEngine::querySaveMetaInfos(const char *target, Common::InSaveFile *in = saveFileMan->openForLoading(saveFileName); if (in) { - desc = loadMetaData(in, slot); + desc = loadMetaData(in, slot, false); delete in; return desc; } diff --git a/engines/macventure/saveload.cpp b/engines/macventure/saveload.cpp index 89a6301318..c63b6a6951 100644 --- a/engines/macventure/saveload.cpp +++ b/engines/macventure/saveload.cpp @@ -42,7 +42,7 @@ namespace MacVenture { #define MACVENTURE_SAVE_VERSION 1 //1 BYTE #define MACVENTURE_DESC_LENGTH 4 //4 BYTE for the metadata length -SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot) { +SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot, bool skipThumbnail) { // Metadata is stored at the end of the file // |THUMBNAIL | // | | @@ -65,8 +65,11 @@ SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot) { s->seek(-(5 + MACVENTURE_DESC_LENGTH + metaSize), SEEK_END); // Load the thumbnail - Graphics::Surface *thumb = Graphics::loadThumbnail(*s); - desc.setThumbnail(thumb); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*s, thumbnail, skipThumbnail)) { + return desc; + } + desc.setThumbnail(thumbnail); // Load the description Common::String name; diff --git a/engines/mads/detection.cpp b/engines/mads/detection.cpp index 4fb8b82eb3..8eb3b4eee9 100644 --- a/engines/mads/detection.cpp +++ b/engines/mads/detection.cpp @@ -203,11 +203,8 @@ SaveStateList MADSMetaEngine::listSaves(const char *target) const { Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); if (in) { - MADS::Game::readSavegameHeader(in, header); - saveList.push_back(SaveStateDescriptor(slot, header._saveName)); - - header._thumbnail->free(); - delete header._thumbnail; + if (MADS::Game::readSavegameHeader(in, header)) + saveList.push_back(SaveStateDescriptor(slot, header._saveName)); delete in; } } @@ -233,7 +230,10 @@ SaveStateDescriptor MADSMetaEngine::querySaveMetaInfos(const char *target, int s if (f) { MADS::MADSSavegameHeader header; - MADS::Game::readSavegameHeader(f, header); + if (!MADS::Game::readSavegameHeader(f, header, false)) { + delete f; + return SaveStateDescriptor(); + } delete f; // Create the return descriptor diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp index 0a6741ba7a..bea0ea3bb4 100644 --- a/engines/mads/game.cpp +++ b/engines/mads/game.cpp @@ -485,11 +485,6 @@ void Game::loadGame(int slotNumber) { if (!readSavegameHeader(_saveFile, header)) error("Invalid savegame"); - if (header._thumbnail) { - header._thumbnail->free(); - delete header._thumbnail; - } - // Load most of the savegame data with the exception of scene specific info synchronize(s, true); @@ -527,9 +522,8 @@ void Game::saveGame(int slotNumber, const Common::String &saveName) { const char *const SAVEGAME_STR = "MADS"; #define SAVEGAME_STR_SIZE 4 -bool Game::readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header) { +WARN_UNUSED_RESULT bool Game::readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header, bool skipThumbnail) { char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; - header._thumbnail = nullptr; // Validate the header Id in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1); @@ -546,9 +540,9 @@ bool Game::readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header while ((ch = (char)in->readByte()) != '\0') header._saveName += ch; // Get the thumbnail - header._thumbnail = Graphics::loadThumbnail(*in); - if (!header._thumbnail) + if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) { return false; + } // Read in save date/time header._year = in->readSint16LE(); diff --git a/engines/mads/game.h b/engines/mads/game.h index 9defb58b1a..b979160f3d 100644 --- a/engines/mads/game.h +++ b/engines/mads/game.h @@ -237,7 +237,7 @@ public: /** * Read in a savegame header */ - static bool readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header); + WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header, bool skipThumbnail = true); /** * Creates a temporary thumbnail for use in saving games diff --git a/engines/mohawk/myst_state.cpp b/engines/mohawk/myst_state.cpp index 213a976413..20b8ec47ae 100644 --- a/engines/mohawk/myst_state.cpp +++ b/engines/mohawk/myst_state.cpp @@ -272,7 +272,12 @@ SaveStateDescriptor MystGameState::querySaveMetaInfos(int slot) { desc.setSaveDate(metadata.saveYear, metadata.saveMonth, metadata.saveDay); desc.setSaveTime(metadata.saveHour, metadata.saveMinute); desc.setPlayTime(metadata.totalPlayTime); - desc.setThumbnail(Graphics::loadThumbnail(*metadataFile)); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*metadataFile, thumbnail)) { + delete metadataFile; + return SaveStateDescriptor(); + } + desc.setThumbnail(thumbnail); delete metadataFile; diff --git a/engines/mohawk/riven_saveload.cpp b/engines/mohawk/riven_saveload.cpp index 7165166d8f..1d9ae211d9 100644 --- a/engines/mohawk/riven_saveload.cpp +++ b/engines/mohawk/riven_saveload.cpp @@ -148,7 +148,11 @@ SaveStateDescriptor RivenSaveLoad::querySaveMetaInfos(const int slot) { return descriptor; } - descriptor.setThumbnail(Graphics::loadThumbnail(*thmbStream)); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*thmbStream, thumbnail)) { + return descriptor; + } + descriptor.setThumbnail(thumbnail); delete thmbStream; diff --git a/engines/mortevielle/saveload.cpp b/engines/mortevielle/saveload.cpp index 3032c96690..078338a0b5 100644 --- a/engines/mortevielle/saveload.cpp +++ b/engines/mortevielle/saveload.cpp @@ -92,8 +92,10 @@ bool SavegameManager::loadSavegame(const Common::String &filename) { if (!strncmp(&buffer[0], &SAVEGAME_ID[0], 4)) { // Yes, it is, so skip over the savegame header SavegameHeader header; - readSavegameHeader(stream, header); - delete header.thumbnail; + if (!readSavegameHeader(stream, header)) { + delete stream; + return false; + } } else { stream->seek(0); } @@ -208,9 +210,7 @@ void SavegameManager::writeSavegameHeader(Common::OutSaveFile *out, const Common out->writeSint16LE(td.tm_min); } -bool SavegameManager::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) { - header.thumbnail = NULL; - +WARN_UNUSED_RESULT bool SavegameManager::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail) { // Get the savegame version header.version = in->readByte(); @@ -221,9 +221,9 @@ bool SavegameManager::readSavegameHeader(Common::InSaveFile *in, SavegameHeader header.saveName += ch; // Get the thumbnail - header.thumbnail = Graphics::loadThumbnail(*in); - if (!header.thumbnail) + if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) { return false; + } // Read in save date/time header.saveYear = in->readSint16LE(); @@ -263,7 +263,6 @@ SaveStateList SavegameManager::listSaves(const Common::String &target) { validFlag = readSavegameHeader(in, header); if (validFlag) { - delete header.thumbnail; saveDescription = header.saveName; } } else if (file->size() == 497) { @@ -311,7 +310,10 @@ SaveStateDescriptor SavegameManager::querySaveMetaInfos(const Common::String &fi } else { // Get the savegame header information SavegameHeader header; - readSavegameHeader(f, header); + if (!readSavegameHeader(f, header, false)) { + delete f; + return SaveStateDescriptor(); + } delete f; // Create the return descriptor diff --git a/engines/mortevielle/saveload.h b/engines/mortevielle/saveload.h index a0de05b920..b401823938 100644 --- a/engines/mortevielle/saveload.h +++ b/engines/mortevielle/saveload.h @@ -65,7 +65,7 @@ public: Common::Error saveGame(int slot); void writeSavegameHeader(Common::OutSaveFile *out, const Common::String &saveName); - static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header); + WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail = true); static SaveStateList listSaves(const Common::String &target); static SaveStateDescriptor querySaveMetaInfos(const Common::String &fileName); }; diff --git a/engines/neverhood/detection.cpp b/engines/neverhood/detection.cpp index 46605bb2f7..920d149659 100644 --- a/engines/neverhood/detection.cpp +++ b/engines/neverhood/detection.cpp @@ -271,7 +271,7 @@ SaveStateList NeverhoodMetaEngine::listSaves(const char *target) const { if (slotNum >= 0 && slotNum <= 999) { Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str()); if (in) { - if (Neverhood::NeverhoodEngine::readSaveHeader(in, false, header) == Neverhood::NeverhoodEngine::kRSHENoError) { + if (Neverhood::NeverhoodEngine::readSaveHeader(in, header) == Neverhood::NeverhoodEngine::kRSHENoError) { saveList.push_back(SaveStateDescriptor(slotNum, header.description)); } delete in; @@ -302,7 +302,7 @@ SaveStateDescriptor NeverhoodMetaEngine::querySaveMetaInfos(const char *target, Neverhood::NeverhoodEngine::SaveHeader header; Neverhood::NeverhoodEngine::kReadSaveHeaderError error; - error = Neverhood::NeverhoodEngine::readSaveHeader(in, true, header); + error = Neverhood::NeverhoodEngine::readSaveHeader(in, header, false); delete in; if (error == Neverhood::NeverhoodEngine::kRSHENoError) { diff --git a/engines/neverhood/menumodule.cpp b/engines/neverhood/menumodule.cpp index e3996a2507..b64f4dcdd2 100644 --- a/engines/neverhood/menumodule.cpp +++ b/engines/neverhood/menumodule.cpp @@ -291,7 +291,7 @@ void MenuModule::loadSavegameList() { if (slotNum >= 0 && slotNum <= 999) { Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str()); if (in) { - if (Neverhood::NeverhoodEngine::readSaveHeader(in, false, header) == Neverhood::NeverhoodEngine::kRSHENoError) { + if (Neverhood::NeverhoodEngine::readSaveHeader(in, header) == Neverhood::NeverhoodEngine::kRSHENoError) { SavegameItem savegameItem; savegameItem.slotNum = slotNum; savegameItem.description = header.description; diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h index 4c5f9c3303..90055eeb9d 100644 --- a/engines/neverhood/neverhood.h +++ b/engines/neverhood/neverhood.h @@ -129,7 +129,7 @@ public: bool loadgame(const char *filename); const char *getSavegameFilename(int num); static Common::String getSavegameFilename(const Common::String &target, int num); - static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header); + WARN_UNUSED_RESULT static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail = true); GameState& gameState() { return _gameState; } GameModule *gameModule() { return _gameModule; } diff --git a/engines/neverhood/saveload.cpp b/engines/neverhood/saveload.cpp index 8fe6c9a155..d7e6f1ebfe 100644 --- a/engines/neverhood/saveload.cpp +++ b/engines/neverhood/saveload.cpp @@ -32,7 +32,7 @@ namespace Neverhood { #define NEVERHOOD_SAVEGAME_VERSION 0 -NeverhoodEngine::kReadSaveHeaderError NeverhoodEngine::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) { +WARN_UNUSED_RESULT NeverhoodEngine::kReadSaveHeaderError NeverhoodEngine::readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail) { header.version = in->readUint32LE(); if (header.version > NEVERHOOD_SAVEGAME_VERSION) @@ -43,10 +43,8 @@ NeverhoodEngine::kReadSaveHeaderError NeverhoodEngine::readSaveHeader(Common::Se while (descriptionLen--) header.description += (char)in->readByte(); - if (loadThumbnail) { - header.thumbnail = Graphics::loadThumbnail(*in); - } else { - Graphics::skipThumbnail(*in); + if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) { + return kRSHEIoError; } // Not used yet, reserved for future usage @@ -110,7 +108,7 @@ bool NeverhoodEngine::loadgame(const char *filename) { SaveHeader header; - kReadSaveHeaderError errorCode = readSaveHeader(in, false, header); + kReadSaveHeaderError errorCode = readSaveHeader(in, header); if (errorCode != kRSHENoError) { warning("Error loading savegame '%s'", filename); diff --git a/engines/prince/detection.cpp b/engines/prince/detection.cpp index ce80fe5cab..ef3128ae09 100644 --- a/engines/prince/detection.cpp +++ b/engines/prince/detection.cpp @@ -208,10 +208,6 @@ SaveStateList PrinceMetaEngine::listSaves(const char *target) const { // Valid savegame if (Prince::PrinceEngine::readSavegameHeader(file, header)) { saveList.push_back(SaveStateDescriptor(slotNum, header.saveName)); - if (header.thumbnail) { - header.thumbnail->free(); - delete header.thumbnail; - } } } else { // Must be an original format savegame @@ -239,7 +235,7 @@ SaveStateDescriptor PrinceMetaEngine::querySaveMetaInfos(const char *target, int f->read(buffer, kSavegameStrSize + 1); bool hasHeader = !strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) && - Prince::PrinceEngine::readSavegameHeader(f, header); + Prince::PrinceEngine::readSavegameHeader(f, header, false); delete f; if (!hasHeader) { diff --git a/engines/prince/prince.h b/engines/prince/prince.h index 32e37e0774..c264125895 100644 --- a/engines/prince/prince.h +++ b/engines/prince/prince.h @@ -290,7 +290,7 @@ public: void playVideo(Common::String videoFilename); - static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header); + WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail = true); Common::String generateSaveName(int slot); void writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header); void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream); diff --git a/engines/prince/saveload.cpp b/engines/prince/saveload.cpp index 14f6078910..8832a6d1d2 100644 --- a/engines/prince/saveload.cpp +++ b/engines/prince/saveload.cpp @@ -44,9 +44,7 @@ namespace Prince { class InterpreterFlags; class Interpreter; -bool PrinceEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) { - header.thumbnail = nullptr; - +WARN_UNUSED_RESULT bool PrinceEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail) { // Get the savegame version header.version = in->readByte(); if (header.version > kSavegameVersion) @@ -59,9 +57,9 @@ bool PrinceEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &he header.saveName += ch; // Get the thumbnail - header.thumbnail = Graphics::loadThumbnail(*in); - if (!header.thumbnail) + if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) { return false; + } // Read in save date/time header.saveYear = in->readSint16LE(); @@ -416,10 +414,6 @@ bool PrinceEngine::loadGame(int slotNumber) { delete readStream; return false; } - - // Delete the thumbnail - saveHeader.thumbnail->free(); - delete saveHeader.thumbnail; } // Get in the savegame diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp index 6fe4277c27..fcd78502d9 100644 --- a/engines/saga/detection.cpp +++ b/engines/saga/detection.cpp @@ -256,7 +256,11 @@ SaveStateDescriptor SagaMetaEngine::querySaveMetaInfos(const char *target, int s } if (version >= 6) { - Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*in, thumbnail)) { + delete in; + return SaveStateDescriptor(); + } desc.setThumbnail(thumbnail); uint32 saveDate = in->readUint32BE(); diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index aa7a63d224..bc7241269d 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -871,7 +871,14 @@ SaveStateDescriptor SciMetaEngine::querySaveMetaInfos(const char *target, int sl descriptor.setDescription(meta.name); - Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*in, thumbnail)) { + // invalid + delete in; + + descriptor.setDescription("*Invalid*"); + return descriptor; + } descriptor.setThumbnail(thumbnail); int day = (meta.saveDate >> 24) & 0xFF; diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index d04b3bb5ad..84dd16efa6 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -706,7 +706,9 @@ bool ScummEngine::querySaveMetaInfos(const char *target, int slot, int heversion if (hdr.ver > VER(52)) { if (Graphics::checkThumbnailHeader(*in)) { - thumbnail = Graphics::loadThumbnail(*in); + if (!Graphics::loadThumbnail(*in, thumbnail)) { + return false; + } } if (hdr.ver > VER(57)) { diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp index 9184fd8e88..a0598dcb46 100644 --- a/engines/sherlock/detection.cpp +++ b/engines/sherlock/detection.cpp @@ -233,7 +233,10 @@ SaveStateDescriptor SherlockMetaEngine::querySaveMetaInfos(const char *target, i if (f) { Sherlock::SherlockSavegameHeader header; - Sherlock::SaveManager::readSavegameHeader(f, header); + if (!Sherlock::SaveManager::readSavegameHeader(f, header, false)) { + delete f; + return SaveStateDescriptor(); + } delete f; // Create the return descriptor diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp index 9d203a6a27..ca27f57a97 100644 --- a/engines/sherlock/saveload.cpp +++ b/engines/sherlock/saveload.cpp @@ -103,13 +103,9 @@ SaveStateList SaveManager::getSavegameList(const Common::String &target) { Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); if (in) { - if (!readSavegameHeader(in, header)) - continue; + if (readSavegameHeader(in, header)) + saveList.push_back(SaveStateDescriptor(slot, header._saveName)); - saveList.push_back(SaveStateDescriptor(slot, header._saveName)); - - header._thumbnail->free(); - delete header._thumbnail; delete in; } } @@ -119,9 +115,8 @@ SaveStateList SaveManager::getSavegameList(const Common::String &target) { return saveList; } -bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header) { +WARN_UNUSED_RESULT bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header, bool skipThumbnail) { char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; - header._thumbnail = nullptr; // Validate the header Id in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1); @@ -138,9 +133,9 @@ bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHea while ((ch = (char)in->readByte()) != '\0') header._saveName += ch; // Get the thumbnail - header._thumbnail = Graphics::loadThumbnail(*in); - if (!header._thumbnail) + if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) { return false; + } // Read in save date/time header._year = in->readSint16LE(); @@ -212,11 +207,6 @@ void SaveManager::loadGame(int slot) { if (!readSavegameHeader(saveFile, header)) error("Invalid savegame"); - if (header._thumbnail) { - header._thumbnail->free(); - delete header._thumbnail; - } - // Synchronize the savegame data Serializer s(saveFile, nullptr); s.setVersion(header._version); diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h index 59b0b26d6e..6348b0f668 100644 --- a/engines/sherlock/saveload.h +++ b/engines/sherlock/saveload.h @@ -105,7 +105,7 @@ public: /** * Read in the header information for a savegame */ - static bool readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header); + WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header, bool skipThumbnail = true); /** * Return the index of the button the mouse is over, if any diff --git a/engines/supernova/detection.cpp b/engines/supernova/detection.cpp index 8e9db14db4..7fd2da1760 100644 --- a/engines/supernova/detection.cpp +++ b/engines/supernova/detection.cpp @@ -200,7 +200,11 @@ SaveStateDescriptor SupernovaMetaEngine::querySaveMetaInfos(const char *target, desc.setPlayTime(playTime * 1000); if (Graphics::checkThumbnailHeader(*savefile)) { - Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*savefile); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*savefile, thumbnail)) { + delete savefile; + return SaveStateDescriptor(); + } desc.setThumbnail(thumbnail); } diff --git a/engines/sword1/detection.cpp b/engines/sword1/detection.cpp index d4343c8a9f..0b81690bc5 100644 --- a/engines/sword1/detection.cpp +++ b/engines/sword1/detection.cpp @@ -300,7 +300,11 @@ SaveStateDescriptor SwordMetaEngine::querySaveMetaInfos(const char *target, int in->skip(1); if (Graphics::checkThumbnailHeader(*in)) { - Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*in, thumbnail)) { + delete in; + return SaveStateDescriptor(); + } desc.setThumbnail(thumbnail); } diff --git a/engines/teenagent/detection.cpp b/engines/teenagent/detection.cpp index caa7bdbec9..e35e7033d5 100644 --- a/engines/teenagent/detection.cpp +++ b/engines/teenagent/detection.cpp @@ -178,8 +178,11 @@ public: SaveStateDescriptor ssd(slot, desc); //checking for the thumbnail - if (Graphics::Surface *const thumb = Graphics::loadThumbnail(*in)) - ssd.setThumbnail(thumb); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*in, thumbnail)) { + return SaveStateDescriptor(); + } + ssd.setThumbnail(thumbnail); return ssd; } diff --git a/engines/titanic/core/project_item.cpp b/engines/titanic/core/project_item.cpp index b2bd5cd92b..6da891c417 100644 --- a/engines/titanic/core/project_item.cpp +++ b/engines/titanic/core/project_item.cpp @@ -190,10 +190,6 @@ void CProjectItem::loadGame(int slotId) { // Load the savegame header in TitanicSavegameHeader header; readSavegameHeader(&file, header); - if (header._thumbnail) { - header._thumbnail->free(); - delete header._thumbnail; - } g_vm->_events->setTotalPlayTicks(header._totalFrames); @@ -488,13 +484,9 @@ SaveStateList CProjectItem::getSavegameList(const Common::String &target) { if (in) { SimpleFile f; f.open(in); - if (!readSavegameHeader(&f, header)) - continue; - - saveList.push_back(SaveStateDescriptor(slot, header._saveName)); + if (readSavegameHeader(&f, header)) + saveList.push_back(SaveStateDescriptor(slot, header._saveName)); - header._thumbnail->free(); - delete header._thumbnail; delete in; } } @@ -503,7 +495,7 @@ SaveStateList CProjectItem::getSavegameList(const Common::String &target) { return saveList; } -bool CProjectItem::readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header) { +bool CProjectItem::readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header, bool skipThumbnail) { char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; header._thumbnail = nullptr; header._totalFrames = 0; @@ -526,8 +518,7 @@ bool CProjectItem::readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &h while ((ch = (char)file->readByte()) != '\0') header._saveName += ch; // Get the thumbnail - header._thumbnail = Graphics::loadThumbnail(*file); - if (!header._thumbnail) + if (!Graphics::loadThumbnail(*file, header._thumbnail, skipThumbnail)) return false; // Read in save date/time diff --git a/engines/titanic/core/project_item.h b/engines/titanic/core/project_item.h index c9fd6f97cb..ef557f7f9d 100644 --- a/engines/titanic/core/project_item.h +++ b/engines/titanic/core/project_item.h @@ -155,7 +155,7 @@ public: /** * Read in the header information for a savegame */ - static bool readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header); + static bool readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header, bool loadThumbnail = false); public: CLASSDEF; CProjectItem(); diff --git a/engines/titanic/detection.cpp b/engines/titanic/detection.cpp index b33ac51bed..c98fbbdade 100644 --- a/engines/titanic/detection.cpp +++ b/engines/titanic/detection.cpp @@ -128,11 +128,6 @@ SaveStateList TitanicMetaEngine::listSaves(const char *target) const { if (Titanic::CProjectItem::readSavegameHeader(&cf, header)) saveList.push_back(SaveStateDescriptor(slot, header._saveName)); - if (header._thumbnail) { - header._thumbnail->free(); - delete header._thumbnail; - } - cf.close(); } } @@ -161,7 +156,10 @@ SaveStateDescriptor TitanicMetaEngine::querySaveMetaInfos(const char *target, in file.open(f); Titanic::TitanicSavegameHeader header; - Titanic::CProjectItem::readSavegameHeader(&file, header); + if (!Titanic::CProjectItem::readSavegameHeader(&file, header, false)) { + file.close(); + return SaveStateDescriptor(); + } file.close(); diff --git a/engines/titanic/pet_control/pet_load_save.cpp b/engines/titanic/pet_control/pet_load_save.cpp index d918478fb1..72770b9eb2 100644 --- a/engines/titanic/pet_control/pet_load_save.cpp +++ b/engines/titanic/pet_control/pet_load_save.cpp @@ -135,11 +135,6 @@ void CPetLoadSave::resetSlots() { _slotNames[idx].setText(header._saveName); } - if (header._thumbnail) { - header._thumbnail->free(); - delete header._thumbnail; - } - file.close(); } } diff --git a/engines/titanic/titanic.cpp b/engines/titanic/titanic.cpp index e0e4a07ce6..5daf399b04 100644 --- a/engines/titanic/titanic.cpp +++ b/engines/titanic/titanic.cpp @@ -49,7 +49,6 @@ #include "common/translation.h" #include "engines/util.h" #include "graphics/scaler.h" -#include "graphics/thumbnail.h" #include "graphics/screen.h" #include "gui/saveload.h" @@ -256,11 +255,6 @@ CString TitanicEngine::getSavegameName(int slot) { TitanicSavegameHeader header; bool isValid = CProjectItem::readSavegameHeader(&file, header); - if (header._thumbnail) { - header._thumbnail->free(); - delete header._thumbnail; - } - file.close(); if (isValid) diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp index 9303760057..0cd9596c8c 100644 --- a/engines/toltecs/detection.cpp +++ b/engines/toltecs/detection.cpp @@ -276,7 +276,7 @@ SaveStateList ToltecsMetaEngine::listSaves(const char *target) const { if (slotNum >= 0 && slotNum <= 999) { Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str()); if (in) { - if (Toltecs::ToltecsEngine::readSaveHeader(in, false, header) == Toltecs::ToltecsEngine::kRSHENoError) { + if (Toltecs::ToltecsEngine::readSaveHeader(in, header) == Toltecs::ToltecsEngine::kRSHENoError) { saveList.push_back(SaveStateDescriptor(slotNum, header.description)); } delete in; @@ -325,7 +325,7 @@ SaveStateDescriptor ToltecsMetaEngine::querySaveMetaInfos(const char *target, in Toltecs::ToltecsEngine::SaveHeader header; Toltecs::ToltecsEngine::kReadSaveHeaderError error; - error = Toltecs::ToltecsEngine::readSaveHeader(in, true, header); + error = Toltecs::ToltecsEngine::readSaveHeader(in, header, false); delete in; if (error == Toltecs::ToltecsEngine::kRSHENoError) { diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp index 5fc0599c2a..c4373265e6 100644 --- a/engines/toltecs/menu.cpp +++ b/engines/toltecs/menu.cpp @@ -525,7 +525,7 @@ int MenuSystem::loadSavegamesList() { if (slotNum >= 0 && slotNum <= 999) { Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str()); if (in) { - if (Toltecs::ToltecsEngine::readSaveHeader(in, false, header) == Toltecs::ToltecsEngine::kRSHENoError) { + if (Toltecs::ToltecsEngine::readSaveHeader(in, header) == Toltecs::ToltecsEngine::kRSHENoError) { _savegames.push_back(SavegameItem(slotNum, header.description)); //debug("%s -> %s", file->c_str(), header.description.c_str()); } diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp index 409fc97076..1f2198fc35 100644 --- a/engines/toltecs/saveload.cpp +++ b/engines/toltecs/saveload.cpp @@ -41,7 +41,7 @@ namespace Toltecs { #define TOLTECS_SAVEGAME_VERSION 4 -ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) { +WARN_UNUSED_RESULT ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail) { header.version = in->readUint32LE(); if (header.version > TOLTECS_SAVEGAME_VERSION) @@ -52,10 +52,8 @@ ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::Seekab while (descriptionLen--) header.description += (char)in->readByte(); - if (loadThumbnail) { - header.thumbnail = Graphics::loadThumbnail(*in); - } else { - Graphics::skipThumbnail(*in); + if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) { + return kRSHEIoError; } // Not used yet, reserved for future usage @@ -147,7 +145,7 @@ void ToltecsEngine::loadgame(const char *filename) { SaveHeader header; - kReadSaveHeaderError errorCode = readSaveHeader(in, false, header); + kReadSaveHeaderError errorCode = readSaveHeader(in, header); if (errorCode != kRSHENoError) { warning("Error loading savegame '%s'", filename); diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h index ece82f4a1a..1c9e9366c7 100644 --- a/engines/toltecs/toltecs.h +++ b/engines/toltecs/toltecs.h @@ -225,7 +225,7 @@ public: const char *getSavegameFilename(int num); static Common::String getSavegameFilename(const Common::String &target, int num); - static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header); + WARN_UNUSED_RESULT static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail = true); }; diff --git a/engines/toon/detection.cpp b/engines/toon/detection.cpp index e93d676d87..6eb38c4883 100644 --- a/engines/toon/detection.cpp +++ b/engines/toon/detection.cpp @@ -232,7 +232,11 @@ SaveStateDescriptor ToonMetaEngine::querySaveMetaInfos(const char *target, int s SaveStateDescriptor desc(slot, saveName); - Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*file); + Graphics::Surface *thumbnail; + if (!Graphics::loadThumbnail(*file, thumbnail)) { + delete file; + return SaveStateDescriptor(); + } desc.setThumbnail(thumbnail); uint32 saveDate = file->readUint32BE(); diff --git a/engines/tsage/detection.cpp b/engines/tsage/detection.cpp index e476391f71..5d31cca75e 100644 --- a/engines/tsage/detection.cpp +++ b/engines/tsage/detection.cpp @@ -131,9 +131,6 @@ public: if (in) { if (TsAGE::Saver::readSavegameHeader(in, header)) { saveList.push_back(SaveStateDescriptor(slot, header._saveName)); - - header._thumbnail->free(); - delete header._thumbnail; } delete in; @@ -161,7 +158,11 @@ public: if (f) { TsAGE::tSageSavegameHeader header; - TsAGE::Saver::readSavegameHeader(f, header); + if (!TsAGE::Saver::readSavegameHeader(f, header, false)) { + delete f; + return SaveStateDescriptor(); + } + delete f; // Create the return descriptor diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp index 03f615db21..81bb973d02 100644 --- a/engines/tsage/saveload.cpp +++ b/engines/tsage/saveload.cpp @@ -189,10 +189,10 @@ Common::Error Saver::restore(int slot) { // Read in the savegame header tSageSavegameHeader header; - readSavegameHeader(saveFile, header); - if (header._thumbnail) - header._thumbnail->free(); - delete header._thumbnail; + if (!readSavegameHeader(saveFile, header)) { + delete saveFile; + return Common::kReadingFailed; + } serializer.setSaveVersion(header._version); @@ -247,9 +247,8 @@ Common::Error Saver::restore(int slot) { const char *SAVEGAME_STR = "SCUMMVM_TSAGE"; #define SAVEGAME_STR_SIZE 13 -bool Saver::readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header) { +WARN_UNUSED_RESULT bool Saver::readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header, bool skipThumbnail) { char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; - header._thumbnail = NULL; // Validate the header Id in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1); @@ -266,9 +265,9 @@ bool Saver::readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &head while ((ch = (char)in->readByte()) != '\0') header._saveName += ch; // Get the thumbnail - header._thumbnail = Graphics::loadThumbnail(*in); - if (!header._thumbnail) + if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) { return false; + } // Read in save date/time header._saveYear = in->readSint16LE(); diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h index 04a1e02b28..3de34489fd 100644 --- a/engines/tsage/saveload.h +++ b/engines/tsage/saveload.h @@ -221,7 +221,7 @@ public: Common::Error save(int slot, const Common::String &saveName); Common::Error restore(int slot); - static bool readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header); + WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header, bool skipThumbnail = true); static void writeSavegameHeader(Common::OutSaveFile *out, tSageSavegameHeader &header); void addListener(SaveListener *obj); diff --git a/engines/tucker/detection.cpp b/engines/tucker/detection.cpp index 7d07edabd3..119d60f23a 100644 --- a/engines/tucker/detection.cpp +++ b/engines/tucker/detection.cpp @@ -175,7 +175,7 @@ public: if (ext && (slot = atoi(ext + 1)) >= 0 && slot <= Tucker::kLastSaveSlot) { Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); if (in) { - if (Tucker::TuckerEngine::readSavegameHeader(in, header, false) == Tucker::TuckerEngine::kSavegameNoError) { + if (Tucker::TuckerEngine::readSavegameHeader(in, header) == Tucker::TuckerEngine::kSavegameNoError) { saveList.push_back(SaveStateDescriptor(slot, header.description)); } @@ -207,7 +207,7 @@ public: } Tucker::TuckerEngine::SavegameHeader header; - Tucker::TuckerEngine::SavegameError savegameError = Tucker::TuckerEngine::readSavegameHeader(file, header, true); + Tucker::TuckerEngine::SavegameError savegameError = Tucker::TuckerEngine::readSavegameHeader(file, header, false); if (savegameError) { delete file; return SaveStateDescriptor(); diff --git a/engines/tucker/saveload.cpp b/engines/tucker/saveload.cpp index a56ced915e..484c47e5da 100644 --- a/engines/tucker/saveload.cpp +++ b/engines/tucker/saveload.cpp @@ -141,7 +141,7 @@ Common::Error TuckerEngine::loadGameState(int slot) { } -TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(const char *target, int slot, SavegameHeader &header) { +WARN_UNUSED_RESULT TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(const char *target, int slot, SavegameHeader &header) { Common::String fileName = generateGameStateFileName(target, slot); Common::InSaveFile *file = g_system->getSavefileManager()->openForLoading(fileName); @@ -155,7 +155,7 @@ TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(const char *target, return savegameError; } -TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(Common::InSaveFile *file, SavegameHeader &header, bool loadThumbnail) { +WARN_UNUSED_RESULT TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(Common::InSaveFile *file, SavegameHeader &header, bool skipThumbnail) { header.version = -1; header.flags = 0; header.description.clear(); @@ -196,10 +196,8 @@ TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(Common::InSaveFile header.saveTime = file->readUint32LE(); header.playTime = file->readUint32LE(); - if (loadThumbnail) { - header.thumbnail = Graphics::loadThumbnail(*file); - } else { - Graphics::skipThumbnail(*file); + if (!Graphics::loadThumbnail(*file, header.thumbnail, skipThumbnail)) { + return kSavegameIoError; } } diff --git a/engines/tucker/tucker.h b/engines/tucker/tucker.h index 4cb427fe35..e3748680fe 100644 --- a/engines/tucker/tucker.h +++ b/engines/tucker/tucker.h @@ -452,8 +452,8 @@ public: virtual bool hasFeature(EngineFeature f) const; GUI::Debugger *getDebugger() { return _console; } - static SavegameError readSavegameHeader(Common::InSaveFile *file, SavegameHeader &header, bool loadThumbnail = false); - static SavegameError readSavegameHeader(const char *target, int slot, SavegameHeader &header); + WARN_UNUSED_RESULT static SavegameError readSavegameHeader(Common::InSaveFile *file, SavegameHeader &header, bool skipThumbnail = true); + WARN_UNUSED_RESULT static SavegameError readSavegameHeader(const char *target, int slot, SavegameHeader &header); bool isAutosaveAllowed(); static bool isAutosaveAllowed(const char *target); protected: diff --git a/engines/voyeur/detection.cpp b/engines/voyeur/detection.cpp index eefe174e94..6452e5741f 100644 --- a/engines/voyeur/detection.cpp +++ b/engines/voyeur/detection.cpp @@ -132,7 +132,6 @@ SaveStateList VoyeurMetaEngine::listSaves(const char *target) const { if (in) { if (header.read(in)) { saveList.push_back(SaveStateDescriptor(slot, header._saveName)); - header._thumbnail->free(); } delete in; } @@ -159,7 +158,7 @@ SaveStateDescriptor VoyeurMetaEngine::querySaveMetaInfos(const char *target, int if (f) { Voyeur::VoyeurSavegameHeader header; - header.read(f); + header.read(f, false); delete f; // Create the return descriptor diff --git a/engines/voyeur/voyeur.cpp b/engines/voyeur/voyeur.cpp index 7f2f0e312e..b7769c1fd4 100644 --- a/engines/voyeur/voyeur.cpp +++ b/engines/voyeur/voyeur.cpp @@ -789,9 +789,6 @@ void VoyeurEngine::loadGame(int slot) { VoyeurSavegameHeader header; if (!header.read(saveFile)) return; - if (header._thumbnail) - header._thumbnail->free(); - delete header._thumbnail; serializer.setVersion(header._version); synchronize(serializer); @@ -856,9 +853,7 @@ void VoyeurEngine::synchronize(Common::Serializer &s) { /*------------------------------------------------------------------------*/ -bool VoyeurSavegameHeader::read(Common::InSaveFile *f) { - _thumbnail = NULL; - +bool VoyeurSavegameHeader::read(Common::InSaveFile *f, bool skipThumbnail) { uint32 signature = f->readUint32BE(); if (signature != MKTAG('V', 'O', 'Y', 'R')) { warning("Invalid savegame"); @@ -875,9 +870,9 @@ bool VoyeurSavegameHeader::read(Common::InSaveFile *f) { _saveName += c; // Get the thumbnail - _thumbnail = Graphics::loadThumbnail(*f); - if (!_thumbnail) + if (!Graphics::loadThumbnail(*f, _thumbnail, skipThumbnail)) { return false; + } // Read in the save datet/ime _saveYear = f->readSint16LE(); diff --git a/engines/voyeur/voyeur.h b/engines/voyeur/voyeur.h index dcd82b24a9..a098ba9e62 100644 --- a/engines/voyeur/voyeur.h +++ b/engines/voyeur/voyeur.h @@ -312,7 +312,7 @@ struct VoyeurSavegameHeader { /** * Read in the header from the specified file */ - bool read(Common::InSaveFile *f); + bool read(Common::InSaveFile *f, bool skipThumbnail = true); /** * Write out header information to the specified file diff --git a/engines/xeen/detection.cpp b/engines/xeen/detection.cpp index 49b74b24a2..abf82188a9 100644 --- a/engines/xeen/detection.cpp +++ b/engines/xeen/detection.cpp @@ -170,12 +170,9 @@ SaveStateList XeenMetaEngine::listSaves(const char *target) const { Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); if (in) { - Xeen::SavesManager::readSavegameHeader(in, header); - saveList.push_back(SaveStateDescriptor(slot, header._saveName)); + if (Xeen::SavesManager::readSavegameHeader(in, header)) + saveList.push_back(SaveStateDescriptor(slot, header._saveName)); - if (header._thumbnail) - header._thumbnail->free(); - delete header._thumbnail; delete in; } } @@ -200,7 +197,11 @@ SaveStateDescriptor XeenMetaEngine::querySaveMetaInfos(const char *target, int s if (f) { Xeen::XeenSavegameHeader header; - Xeen::SavesManager::readSavegameHeader(f, header); + if (!Xeen::SavesManager::readSavegameHeader(f, header, false)) { + delete f; + return SaveStateDescriptor(); + } + delete f; // Create the return descriptor diff --git a/engines/xeen/saves.cpp b/engines/xeen/saves.cpp index 1f58562bf0..2f290960d3 100644 --- a/engines/xeen/saves.cpp +++ b/engines/xeen/saves.cpp @@ -48,9 +48,8 @@ SavesManager::~SavesManager() { const char *const SAVEGAME_STR = "XEEN"; #define SAVEGAME_STR_SIZE 6 -bool SavesManager::readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader &header) { +WARN_UNUSED_RESULT bool SavesManager::readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader &header, bool skipThumbnail) { char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; - header._thumbnail = nullptr; // Validate the header Id in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1); @@ -68,9 +67,9 @@ bool SavesManager::readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader header._saveName += ch; // Get the thumbnail - header._thumbnail = Graphics::loadThumbnail(*in); - if (!header._thumbnail) + if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) { return false; + } // Read in save date/time header._year = in->readSint16LE(); @@ -168,11 +167,6 @@ Common::Error SavesManager::loadGameState(int slot) { if (!readSavegameHeader(saveFile, header)) error("Invalid savegame"); - if (header._thumbnail) { - header._thumbnail->free(); - delete header._thumbnail; - } - // Set the total play time events.setPlayTime(header._totalFrames); diff --git a/engines/xeen/saves.h b/engines/xeen/saves.h index b18e04a822..9b1bea62a3 100644 --- a/engines/xeen/saves.h +++ b/engines/xeen/saves.h @@ -65,7 +65,7 @@ public: /** * Read in a savegame header */ - static bool readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader &header); + WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader &header, bool skipThumbnail = true); /** * Write out a savegame header diff --git a/engines/zvision/detection.cpp b/engines/zvision/detection.cpp index 5e535a9954..896ea52344 100644 --- a/engines/zvision/detection.cpp +++ b/engines/zvision/detection.cpp @@ -178,7 +178,7 @@ SaveStateDescriptor ZVisionMetaEngine::querySaveMetaInfos(const char *target, in // We only use readSaveGameHeader() here, which doesn't need an engine callback ZVision::SaveManager *zvisionSaveMan = new ZVision::SaveManager(NULL); - bool successfulRead = zvisionSaveMan->readSaveGameHeader(in, header); + bool successfulRead = zvisionSaveMan->readSaveGameHeader(in, header, false); delete zvisionSaveMan; delete in; diff --git a/engines/zvision/file/save_manager.cpp b/engines/zvision/file/save_manager.cpp index 4259937a3b..b33d33cdf1 100644 --- a/engines/zvision/file/save_manager.cpp +++ b/engines/zvision/file/save_manager.cpp @@ -189,7 +189,7 @@ Common::Error SaveManager::loadGame(int slot) { return Common::kNoError; } -bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) { +bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header, bool skipThumbnail) { uint32 tag = in->readUint32BE(); // Check if it's original savegame than fill header structure if (tag == MKTAG('Z', 'N', 'S', 'G')) { @@ -232,9 +232,9 @@ bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &hea header.saveName += ch; // Get the thumbnail - header.thumbnail = Graphics::loadThumbnail(*in); - if (!header.thumbnail) + if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) { return false; + } // Read in save date/time header.saveYear = in->readSint16LE(); diff --git a/engines/zvision/file/save_manager.h b/engines/zvision/file/save_manager.h index 9e816373ea..94885b650b 100644 --- a/engines/zvision/file/save_manager.h +++ b/engines/zvision/file/save_manager.h @@ -94,7 +94,7 @@ public: Common::Error loadGame(int slot); Common::SeekableReadStream *getSlotFile(uint slot); - bool readSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &header); + bool readSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &header, bool skipThumbnail = true); void prepareSaveBuffer(); void flushSaveBuffer(); diff --git a/graphics/thumbnail.cpp b/graphics/thumbnail.cpp index a3037e5ad5..72a06f91ec 100644 --- a/graphics/thumbnail.cpp +++ b/graphics/thumbnail.cpp @@ -147,7 +147,11 @@ bool skipThumbnail(Common::SeekableReadStream &in) { return true; } -Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) { +bool loadThumbnail(Common::SeekableReadStream &in, Graphics::Surface *&thumbnail, bool skipThumbnail) { + if (skipThumbnail) { + return Graphics::skipThumbnail(in); + } + const uint32 position = in.pos(); ThumbnailHeader header; HeaderState headerState = loadHeader(in, header, true); @@ -160,32 +164,32 @@ Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) { // stream at this point then. if (headerState == kHeaderNone) { in.seek(position, SEEK_SET); - return 0; + return false; } else if (headerState == kHeaderUnsupported) { in.seek(header.size - (in.pos() - position), SEEK_CUR); - return 0; + return false; } if (header.format.bytesPerPixel != 2 && header.format.bytesPerPixel != 4) { warning("trying to load thumbnail with unsupported bit depth %d", header.format.bytesPerPixel); - return 0; + return false; } - Graphics::Surface *const to = new Graphics::Surface(); - to->create(header.width, header.height, header.format); + thumbnail = new Graphics::Surface(); + thumbnail->create(header.width, header.height, header.format); - for (int y = 0; y < to->h; ++y) { + for (int y = 0; y < thumbnail->h; ++y) { switch (header.format.bytesPerPixel) { case 2: { - uint16 *pixels = (uint16 *)to->getBasePtr(0, y); - for (uint x = 0; x < to->w; ++x) { + uint16 *pixels = (uint16 *)thumbnail->getBasePtr(0, y); + for (uint x = 0; x < thumbnail->w; ++x) { *pixels++ = in.readUint16BE(); } } break; case 4: { - uint32 *pixels = (uint32 *)to->getBasePtr(0, y); - for (uint x = 0; x < to->w; ++x) { + uint32 *pixels = (uint32 *)thumbnail->getBasePtr(0, y); + for (uint x = 0; x < thumbnail->w; ++x) { *pixels++ = in.readUint32BE(); } } break; @@ -194,7 +198,7 @@ Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) { assert(0); } } - return to; + return true; } bool saveThumbnail(Common::WriteStream &out) { diff --git a/graphics/thumbnail.h b/graphics/thumbnail.h index cec3d02800..17ce856e23 100644 --- a/graphics/thumbnail.h +++ b/graphics/thumbnail.h @@ -52,7 +52,7 @@ bool skipThumbnail(Common::SeekableReadStream &in); /** * Loads a thumbnail from the given input stream. */ -Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in); +bool loadThumbnail(Common::SeekableReadStream &in, Graphics::Surface *&thumbnail, bool skipThumbnail = false); /** * Saves a thumbnail to the given write stream. |