diff options
Diffstat (limited to 'engines/hugo/file.cpp')
-rw-r--r-- | engines/hugo/file.cpp | 370 |
1 files changed, 161 insertions, 209 deletions
diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp index fa8d5b9947..78bcc46e85 100644 --- a/engines/hugo/file.cpp +++ b/engines/hugo/file.cpp @@ -39,17 +39,20 @@ #include "hugo/schedule.h" #include "hugo/display.h" #include "hugo/util.h" +#include "hugo/object.h" namespace Hugo { -FileManager::FileManager(HugoEngine &vm) : _vm(vm) { +FileManager::FileManager(HugoEngine *vm) : _vm(vm) { } FileManager::~FileManager() { } +/** +* Convert 4 planes (RGBI) data to 8-bit DIB format +* Return original plane data ptr +*/ byte *FileManager::convertPCC(byte *p, uint16 y, uint16 bpl, image_pt dataPtr) { -// Convert 4 planes (RGBI) data to 8-bit DIB format -// Return original plane data ptr debugC(2, kDebugFile, "convertPCC(byte *p, %d, %d, image_pt data_p)", y, bpl); dataPtr += y * bpl * 8; // Point to correct DIB line @@ -64,10 +67,12 @@ byte *FileManager::convertPCC(byte *p, uint16 y, uint16 bpl, image_pt dataPtr) { return p; } +/** +* Read a pcx file of length len. Use supplied seq_p and image_p or +* allocate space if NULL. Name used for errors. Returns address of seq_p +* Set first TRUE to initialize b_index (i.e. not reading a sequential image in file). +*/ seq_t *FileManager::readPCX(Common::File &f, seq_t *seqPtr, byte *imagePtr, bool firstFl, const char *name) { -// Read a pcx file of length len. Use supplied seq_p and image_p or -// allocate space if NULL. Name used for errors. Returns address of seq_p -// Set first TRUE to initialize b_index (i.e. not reading a sequential image in file). debugC(1, kDebugFile, "readPCX(..., %s)", name); // Read in the PCC header and check consistency @@ -89,14 +94,14 @@ seq_t *FileManager::readPCX(Common::File &f, seq_t *seqPtr, byte *imagePtr, bool f.read(PCC_header.fill2, sizeof(PCC_header.fill2)); if (PCC_header.mfctr != 10) - Utils::Error(PCCH_ERR, "%s", name); + error("Bad data file format: %s", name); // Allocate memory for seq_t if 0 if (seqPtr == 0) { if ((seqPtr = (seq_t *)malloc(sizeof(seq_t))) == 0) - Utils::Error(HEAP_ERR, "%s", name); + error("Insufficient memory to run game."); } - + // Find size of image data in 8-bit DIB format // Note save of x2 - marks end of valid data before garbage uint16 bytesPerLine4 = PCC_header.bytesPerLine * 4; // 4-bit bpl @@ -108,9 +113,9 @@ seq_t *FileManager::readPCX(Common::File &f, seq_t *seqPtr, byte *imagePtr, bool // Allocate memory for image data if NULL if (imagePtr == 0) { - if ((imagePtr = (byte *)malloc((size_t) size)) == 0) - Utils::Error(HEAP_ERR, "%s", name); + imagePtr = (byte *)malloc((size_t) size); } + assert(imagePtr); seqPtr->imagePtr = imagePtr; @@ -136,14 +141,24 @@ seq_t *FileManager::readPCX(Common::File &f, seq_t *seqPtr, byte *imagePtr, bool return seqPtr; } +/** +* Read object file of PCC images into object supplied +*/ void FileManager::readImage(int objNum, object_t *objPtr) { -// Read object file of PCC images into object supplied debugC(1, kDebugFile, "readImage(%d, object_t *objPtr)", objNum); + /** + * Structure of object file lookup entry + */ + struct objBlock_t { + uint32 objOffset; + uint32 objLength; + }; + if (!objPtr->seqNumb) // This object has no images return; - if (_vm.isPacked()) { + if (_vm->isPacked()) { _objectsArchive.seek((uint32)objNum * sizeof(objBlock_t), SEEK_SET); objBlock_t objBlock; // Info on file within database @@ -153,13 +168,14 @@ void FileManager::readImage(int objNum, object_t *objPtr) { _objectsArchive.seek(objBlock.objOffset, SEEK_SET); } else { char *buf = (char *) malloc(2048 + 1); // Buffer for file access - strcat(strcat(strcpy(buf, _vm._picDir), _vm._arrayNouns[objPtr->nounIndex][0]), OBJEXT); + strcat(strcat(strcpy(buf, _vm->_picDir), _vm->_arrayNouns[objPtr->nounIndex][0]), OBJEXT); if (!_objectsArchive.open(buf)) { - warning("File %s not found, trying again with %s%s", buf, _vm._arrayNouns[objPtr->nounIndex][0], OBJEXT); - strcat(strcpy(buf, _vm._arrayNouns[objPtr->nounIndex][0]), OBJEXT); + warning("File %s not found, trying again with %s%s", buf, _vm->_arrayNouns[objPtr->nounIndex][0], OBJEXT); + strcat(strcpy(buf, _vm->_arrayNouns[objPtr->nounIndex][0]), OBJEXT); if (!_objectsArchive.open(buf)) - Utils::Error(FILE_ERR, "%s", buf); + error("File not found: %s", buf); } + free(buf); } bool firstFl = true; // Initializes pcx read function @@ -170,12 +186,12 @@ void FileManager::readImage(int objNum, object_t *objPtr) { for (int k = 0; k < objPtr->seqList[j].imageNbr; k++) { // each image if (k == 0) { // First image // Read this image - allocate both seq and image memory - seqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm._arrayNouns[objPtr->nounIndex][0]); + seqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm->_arrayNouns[objPtr->nounIndex][0]); objPtr->seqList[j].seqPtr = seqPtr; firstFl = false; } else { // Subsequent image // Read this image - allocate both seq and image memory - seqPtr->nextSeqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm._arrayNouns[objPtr->nounIndex][0]); + seqPtr->nextSeqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm->_arrayNouns[objPtr->nounIndex][0]); seqPtr = seqPtr->nextSeqPtr; } @@ -203,6 +219,7 @@ void FileManager::readImage(int objNum, object_t *objPtr) { } } } + assert(seqPtr); seqPtr->nextSeqPtr = objPtr->seqList[j].seqPtr; // loop linked list to head } @@ -221,17 +238,19 @@ void FileManager::readImage(int objNum, object_t *objPtr) { warning("Unexpected cycling: %d", objPtr->cycling); } - if (!_vm.isPacked()) + if (!_vm->isPacked()) _objectsArchive.close(); } +/** +* Read sound (or music) file data. Call with SILENCE to free-up +* any allocated memory. Also returns size of data +*/ sound_pt FileManager::getSound(int16 sound, uint16 *size) { -// Read sound (or music) file data. Call with SILENCE to free-up -// any allocated memory. Also returns size of data debugC(1, kDebugFile, "getSound(%d, %d)", sound, *size); // No more to do if SILENCE (called for cleanup purposes) - if (sound == _vm._soundSilence) + if (sound == _vm->_soundSilence) return 0; // Open sounds file @@ -247,163 +266,129 @@ sound_pt FileManager::getSound(int16 sound, uint16 *size) { if (!has_read_header) { if (fp.read(s_hdr, sizeof(s_hdr)) != sizeof(s_hdr)) - Utils::Error(FILE_ERR, "%s", SOUND_FILE); + error("Wrong sound file format: %s", SOUND_FILE); has_read_header = true; } *size = s_hdr[sound].size; if (*size == 0) - Utils::Error(SOUND_ERR, "%s", SOUND_FILE); + error("Wrong sound file format or missing sound %d: %s", sound, SOUND_FILE); // Allocate memory for sound or music, if possible sound_pt soundPtr = (byte *)malloc(s_hdr[sound].size); // Ptr to sound data - if (soundPtr == 0) { - Utils::Warn("%s", "Low on memory"); - return 0; - } + assert(soundPtr); // Seek to data and read it fp.seek(s_hdr[sound].offset, SEEK_SET); if (fp.read(soundPtr, s_hdr[sound].size) != s_hdr[sound].size) - Utils::Error(FILE_ERR, "%s", SOUND_FILE); + error("File not found: %s", SOUND_FILE); fp.close(); return soundPtr; } +/** +* Return whether file exists or not +*/ bool FileManager::fileExists(char *filename) { -// Return whether file exists or not Common::File f; - if (f.open(filename)) { - f.close(); - return true; - } - return false; -} - -void FileManager::saveSeq(object_t *obj) { -// Save sequence number and image number in given object - debugC(1, kDebugFile, "saveSeq"); - - bool found = false; - for (int j = 0; !found && (j < obj->seqNumb); j++) { - seq_t *q = obj->seqList[j].seqPtr; - for (int k = 0; !found && (k < obj->seqList[j].imageNbr); k++) { - if (obj->currImagePtr == q) { - found = true; - obj->curSeqNum = j; - obj->curImageNum = k; - } else { - q = q->nextSeqPtr; - } - } - } -} - -void FileManager::restoreSeq(object_t *obj) { -// Set up cur_seq_p from stored sequence and image number in object - debugC(1, kDebugFile, "restoreSeq"); - - seq_t *q = obj->seqList[obj->curSeqNum].seqPtr; - for (int j = 0; j < obj->curImageNum; j++) - q = q->nextSeqPtr; - obj->currImagePtr = q; + return(f.exists(filename)); } +/** +* Save game to supplied slot +*/ void FileManager::saveGame(int16 slot, const char *descrip) { -// Save game to supplied slot (-1 is INITFILE) debugC(1, kDebugFile, "saveGame(%d, %s)", slot, descrip); // Get full path of saved game file - note test for INITFILE - Common::String path; // Full path of saved game - - if (slot == -1) - path = _vm._initFilename; - else - path = Common::String::printf(_vm._saveFilename.c_str(), slot); - - Common::WriteStream *out = _vm.getSaveFileManager()->openForSaving(path); + Common::String path = Common::String::format(_vm->_saveFilename.c_str(), slot); + Common::WriteStream *out = _vm->getSaveFileManager()->openForSaving(path); if (!out) { warning("Can't create file '%s', game not saved", path.c_str()); return; } // Write version. We can't restore from obsolete versions - out->write(&kSavegameVersion, sizeof(kSavegameVersion)); + out->writeByte(kSavegameVersion); // Save description of saved game out->write(descrip, DESCRIPLEN); - // Save objects - for (int i = 0; i < _vm._numObj; i++) { - // Save where curr_seq_p is pointing to - saveSeq(&_vm._objects[i]); - out->write(&_vm._objects[i], sizeof(object_t)); - } + _vm->_object->saveObjects(out); - const status_t &gameStatus = _vm.getGameStatus(); + const status_t &gameStatus = _vm->getGameStatus(); // Save whether hero image is swapped - out->write(&_vm._heroImage, sizeof(_vm._heroImage)); + out->writeByte(_vm->_heroImage); // Save score - int score = _vm.getScore(); - out->write(&score, sizeof(score)); + out->writeSint16BE(_vm->getScore()); // Save story mode - out->write(&gameStatus.storyModeFl, sizeof(gameStatus.storyModeFl)); + out->writeByte((gameStatus.storyModeFl) ? 1 : 0); // Save jumpexit mode - out->write(&gameStatus.jumpExitFl, sizeof(gameStatus.jumpExitFl)); + out->writeByte((gameStatus.jumpExitFl) ? 1 : 0); // Save gameover status - out->write(&gameStatus.gameOverFl, sizeof(gameStatus.gameOverFl)); + out->writeByte((gameStatus.gameOverFl) ? 1 : 0); // Save screen states - out->write(_vm._screenStates, sizeof(*_vm._screenStates) * _vm._numScreens); + for (int i = 0; i < _vm->_numScreens; i++) + out->writeByte(_vm->_screenStates[i]); // Save points table - out->write(_vm._points, sizeof(point_t) * _vm._numBonuses); + for (int i = 0; i < _vm->_numBonuses; i++) { + out->writeByte(_vm->_points[i].score); + out->writeByte((_vm->_points[i].scoredFl) ? 1 : 0); + } // Now save current time and all current events in event queue - _vm.scheduler().saveEvents(out); + _vm->_scheduler->saveEvents(out); // Save palette table - _vm.screen().savePal(out); + _vm->_screen->savePal(out); // Save maze status - out->write(&_maze, sizeof(maze_t)); + out->writeByte((_maze.enabledFl) ? 1 : 0); + out->writeByte(_maze.size); + out->writeSint16BE(_maze.x1); + out->writeSint16BE(_maze.y1); + out->writeSint16BE(_maze.x2); + out->writeSint16BE(_maze.y2); + out->writeSint16BE(_maze.x3); + out->writeSint16BE(_maze.x4); + out->writeByte(_maze.firstScreenIndex); out->finalize(); delete out; } +/** +* Restore game from supplied slot number +*/ void FileManager::restoreGame(int16 slot) { -// Restore game from supplied slot number (-1 is INITFILE) debugC(1, kDebugFile, "restoreGame(%d)", slot); // Initialize new-game status - _vm.initStatus(); + _vm->initStatus(); // Get full path of saved game file - note test for INITFILE Common::String path; // Full path of saved game - if (slot == -1) - path = _vm._initFilename; - else - path = Common::String::printf(_vm._saveFilename.c_str(), slot); + path = Common::String::format(_vm->_saveFilename.c_str(), slot); - Common::SeekableReadStream *in = _vm.getSaveFileManager()->openForLoading(path); + Common::SeekableReadStream *in = _vm->getSaveFileManager()->openForLoading(path); if (!in) return; // Check version, can't restore from different versions - int saveVersion; - in->read(&saveVersion, sizeof(saveVersion)); + int saveVersion = in->readByte(); if (saveVersion != kSavegameVersion) { - Utils::Error(GEN_ERR, "%s", "Savegame of incompatible version"); + error("Savegame of incompatible version"); return; } @@ -411,120 +396,72 @@ void FileManager::restoreGame(int16 slot) { in->seek(DESCRIPLEN, SEEK_CUR); // If hero image is currently swapped, swap it back before restore - if (_vm._heroImage != HERO) - _vm.scheduler().swapImages(HERO, _vm._heroImage); - - // Restore objects, retain current seqList which points to dynamic mem - // Also, retain cmnd_t pointers - for (int i = 0; i < _vm._numObj; i++) { - object_t *p = &_vm._objects[i]; - seqList_t seqList[MAX_SEQUENCES]; - memcpy(seqList, p->seqList, sizeof(seqList_t)); - uint16 cmdIndex = p->cmdIndex; - in->read(p, sizeof(object_t)); - p->cmdIndex = cmdIndex; - memcpy(p->seqList, seqList, sizeof(seqList_t)); - } + if (_vm->_heroImage != HERO) + _vm->_object->swapImages(HERO, _vm->_heroImage); + + _vm->_object->restoreObjects(in); - in->read(&_vm._heroImage, sizeof(_vm._heroImage)); + _vm->_heroImage = in->readByte(); // If hero swapped in saved game, swap it - int heroImg = _vm._heroImage; + byte heroImg = _vm->_heroImage; if (heroImg != HERO) - _vm.scheduler().swapImages(HERO, _vm._heroImage); - _vm._heroImage = heroImg; + _vm->_object->swapImages(HERO, _vm->_heroImage); + _vm->_heroImage = heroImg; - status_t &gameStatus = _vm.getGameStatus(); + status_t &gameStatus = _vm->getGameStatus(); - int score; - in->read(&score, sizeof(score)); - _vm.setScore(score); + int score = in->readSint16BE(); + _vm->setScore(score); - in->read(&gameStatus.storyModeFl, sizeof(gameStatus.storyModeFl)); - in->read(&gameStatus.jumpExitFl, sizeof(gameStatus.jumpExitFl)); - in->read(&gameStatus.gameOverFl, sizeof(gameStatus.gameOverFl)); - in->read(_vm._screenStates, sizeof(*_vm._screenStates) * _vm._numScreens); + gameStatus.storyModeFl = (in->readByte() == 1); + gameStatus.jumpExitFl = (in->readByte() == 1); + gameStatus.gameOverFl = (in->readByte() == 1); + for (int i = 0; i < _vm->_numScreens; i++) + _vm->_screenStates[i] = in->readByte(); // Restore points table - in->read(_vm._points, sizeof(point_t) * _vm._numBonuses); + for (int i = 0; i < _vm->_numBonuses; i++) { + _vm->_points[i].score = in->readByte(); + _vm->_points[i].scoredFl = (in->readByte() == 1); + } - // Restore ptrs to currently loaded objects - for (int i = 0; i < _vm._numObj; i++) - restoreSeq(&_vm._objects[i]); + _vm->_object->restoreAllSeq(); // Now restore time of the save and the event queue - _vm.scheduler().restoreEvents(in); + _vm->_scheduler->restoreEvents(in); // Restore palette and change it if necessary - _vm.screen().restorePal(in); + _vm->_screen->restorePal(in); // Restore maze status - in->read(&_maze, sizeof(maze_t)); - - delete in; -} - -void FileManager::initSavedGame() { -// Initialize the size of a saved game (from the fixed initial game). -// If status.initsave is TRUE, or the initial saved game is not found, -// force a save to create one. Normally the game will be shipped with -// the initial game file but useful to force a write during development -// when the size is changeable. -// The net result is a valid INITFILE, with status.savesize initialized. - debugC(1, kDebugFile, "initSavedGame"); - - // Force save of initial game - if (_vm.getGameStatus().initSaveFl) - saveGame(-1, ""); - - // If initial game doesn't exist, create it - Common::SeekableReadStream *in = _vm.getSaveFileManager()->openForLoading(_vm._initFilename); - if (!in) { - saveGame(-1, ""); - in = _vm.getSaveFileManager()->openForLoading(_vm._initFilename); - if (!in) { - Utils::Error(WRITE_ERR, "%s", _vm._initFilename.c_str()); - return; - } - } + _maze.enabledFl = (in->readByte() == 1); + _maze.size = in->readByte(); + _maze.x1 = in->readSint16BE(); + _maze.y1 = in->readSint16BE(); + _maze.x2 = in->readSint16BE(); + _maze.y2 = in->readSint16BE(); + _maze.x3 = in->readSint16BE(); + _maze.x4 = in->readSint16BE(); + _maze.firstScreenIndex = in->readByte(); - // Must have an open saved game now - _vm.getGameStatus().saveSize = in->size(); delete in; - - // Check sanity - maybe disk full or path set to read-only drive? - if (_vm.getGameStatus().saveSize == -1) - Utils::Error(WRITE_ERR, "%s", _vm._initFilename.c_str()); -} - -void FileManager::openPlaybackFile(bool playbackFl, bool recordFl) { - debugC(1, kDebugFile, "openPlaybackFile(%d, %d)", (playbackFl) ? 1 : 0, (recordFl) ? 1 : 0); - - if (playbackFl) { - if (!(fpb = fopen(PBFILE, "r+b"))) - Utils::Error(FILE_ERR, "%s", PBFILE); - } else if (recordFl) { - fpb = fopen(PBFILE, "wb"); - } - pbdata.time = 0; // Say no key available -} - -void FileManager::closePlaybackFile() { - fclose(fpb); } +/** +* Read the encrypted text from the boot file and print it +*/ void FileManager::printBootText() { -// Read the encrypted text from the boot file and print it debugC(1, kDebugFile, "printBootText"); Common::File ofp; if (!ofp.open(BOOTFILE)) { - if (_vm._gameVariant == 3) { + if (_vm->_gameVariant == 3) { //TODO initialize properly _boot structure warning("printBootText - Skipping as H1 Dos may be a freeware"); return; } else { - Utils::Error(FILE_ERR, "%s", BOOTFILE); + error("Missing startup file"); } } @@ -534,7 +471,7 @@ void FileManager::printBootText() { // Skip over the boot structure (already read) and read exit text ofp.seek((long)sizeof(_boot), SEEK_SET); if (ofp.read(buf, _boot.exit_len) != (size_t)_boot.exit_len) - Utils::Error(FILE_ERR, "%s", BOOTFILE); + error("Error while reading startup file"); // Decrypt the exit text, using CRYPT substring int i; @@ -542,33 +479,33 @@ void FileManager::printBootText() { buf[i] ^= CRYPT[i % strlen(CRYPT)]; buf[i] = '\0'; - //Box(BOX_OK, "%s", buf_p); - //MessageBox(hwnd, buf_p, "License", MB_ICONINFORMATION); - warning("printBootText(): License: %s", buf); + Utils::Box(BOX_OK, "%s", buf); } free(buf); ofp.close(); } +/** +* Reads boot file for program environment. Fatal error if not there or +* file checksum is bad. De-crypts structure while checking checksum +*/ void FileManager::readBootFile() { -// Reads boot file for program environment. Fatal error if not there or -// file checksum is bad. De-crypts structure while checking checksum debugC(1, kDebugFile, "readBootFile"); Common::File ofp; if (!ofp.open(BOOTFILE)) { - if (_vm._gameVariant == 3) { + if (_vm->_gameVariant == 3) { //TODO initialize properly _boot structure warning("readBootFile - Skipping as H1 Dos may be a freeware"); return; } else { - Utils::Error(FILE_ERR, "%s", BOOTFILE); + error("Missing startup file"); } } if (ofp.size() < (int32)sizeof(_boot)) - Utils::Error(FILE_ERR, "%s", BOOTFILE); + error("Corrupted startup file"); _boot.checksum = ofp.readByte(); _boot.registered = ofp.readByte(); @@ -586,11 +523,13 @@ void FileManager::readBootFile() { ofp.close(); if (checksum) - Utils::Error(GEN_ERR, "%s", "Program startup file invalid"); + error("Corrupted startup file"); } +/** +* Returns address of uif_hdr[id], reading it in if first call +*/ uif_hdr_t *FileManager::getUIFHeader(uif_t id) { -// Returns address of uif_hdr[id], reading it in if first call debugC(1, kDebugFile, "getUIFHeader(%d)", id); static bool firstFl = true; @@ -602,10 +541,10 @@ uif_hdr_t *FileManager::getUIFHeader(uif_t id) { // Open unbuffered to do far read Common::File ip; // Image data file if (!ip.open(UIF_FILE)) - Utils::Error(FILE_ERR, "%s", UIF_FILE); + error("File not found: %s", UIF_FILE); if (ip.size() < (int32)sizeof(UIFHeader)) - Utils::Error(FILE_ERR, "%s", UIF_FILE); + error("Wrong file format: %s", UIF_FILE); for (int i = 0; i < MAX_UIFS; ++i) { UIFHeader[i].size = ip.readUint16LE(); @@ -617,38 +556,42 @@ uif_hdr_t *FileManager::getUIFHeader(uif_t id) { return &UIFHeader[id]; } +/** +* Read uif item into supplied buffer. +*/ void FileManager::readUIFItem(int16 id, byte *buf) { -// Read uif item into supplied buffer. debugC(1, kDebugFile, "readUIFItem(%d, ...)", id); // Open uif file to read data Common::File ip; // UIF_FILE handle if (!ip.open(UIF_FILE)) - Utils::Error(FILE_ERR, "%s", UIF_FILE); + error("File not found: %s", UIF_FILE); // Seek to data uif_hdr_t *UIFHeaderPtr = getUIFHeader((uif_t)id); ip.seek(UIFHeaderPtr->offset, SEEK_SET); // We support pcx images and straight data - seq_t dummySeq; // Dummy seq_t for image data + seq_t *dummySeq; // Dummy seq_t for image data switch (id) { case UIF_IMAGES: // Read uif images file - readPCX(ip, &dummySeq, buf, true, UIF_FILE); + dummySeq = readPCX(ip, 0, buf, true, UIF_FILE); + free(dummySeq); break; default: // Read file data into supplied array if (ip.read(buf, UIFHeaderPtr->size) != UIFHeaderPtr->size) - Utils::Error(FILE_ERR, "%s", UIF_FILE); + error("Wrong file format: %s", UIF_FILE); break; } ip.close(); } +/** +* Simple instructions given when F1 pressed twice in a row +* Only in DOS versions +*/ void FileManager::instructions() { -// Simple instructions given when F1 pressed twice in a row -// Only in DOS versions - Common::File f; if (!f.open(HELPFILE)) { warning("help.dat not found"); @@ -672,5 +615,14 @@ void FileManager::instructions() { f.close(); } +/** +* Read the uif image file (inventory icons) +*/ +void FileManager::readUIFImages() { + debugC(1, kDebugFile, "readUIFImages"); + + readUIFItem(UIF_IMAGES, _vm->_screen->getGUIBuffer()); // Read all uif images +} + } // End of namespace Hugo |