bool OEBPlugin::readLanguageAndEncoding(Book &book) const { if (book.language().empty()) { shared_ptr<ZLInputStream> oebStream = new OEBTextStream(opfFile(book.file())); detectLanguage(book, *oebStream, book.encoding()); } return true; }
void scriptDetect(Pixa* pixa, string fileName){ int n = pixaGetCount(pixa); Pix* page = pixaGetPix(pixa, n-1, L_CLONE); l_float32 conf; string language = detectLanguage(page, &conf); printf("%s = %s (%.2f)\n", fileName.c_str(), language.c_str(), conf); }
bool OEBPlugin::readDescription(const std::string &path, DBBook &book) const { fb::shared_ptr<ZLInputStream> lock = ZLFile(path).inputStream(); const std::string opf = opfFileName(path); bool code = OEBDescriptionReader(book).readDescription(opf); if (code && book.language().empty()) { fb::shared_ptr<ZLInputStream> oebStream = new OEBTextStream(opf); detectLanguage(book, *oebStream); } return code; }
bool OEBPlugin::readMetaInfo(Book &book) const { const ZLFile &file = book.file(); shared_ptr<ZLInputStream> lock = file.inputStream(); const ZLFile opfFile = this->opfFile(file); bool code = OEBMetaInfoReader(book).readMetaInfo(opfFile); if (code && book.language().empty()) { shared_ptr<ZLInputStream> oebStream = new OEBTextStream(opfFile); detectLanguage(book, *oebStream); } return code; }
bool DocPlugin::readMetaInfo(Book &book) const { if (!DocMetaInfoReader(book).readMetaInfo()) { return false; } shared_ptr<ZLInputStream> stream = new DocCharStream(book.file(), 50000); if (!detectEncodingAndLanguage(book, *stream)) { stream = new DocAnsiStream(book.file(), 50000); detectLanguage(book, *stream, ZLEncodingConverter::UTF8, true); } return true; }
bool RtfPlugin::readMetaInfo(Book &book) const { if (!RtfDescriptionReader(book).readDocument(book.file())) { return false; } if (book.encoding().empty()) { book.setEncoding("utf-8"); } else if (book.language().empty()) { shared_ptr<ZLInputStream> stream = new RtfReaderStream(book.file(), 50000); if (!stream.isNull()) { detectLanguage(book, *stream); } } return true; }
static void computeGameSettingsFromMD5(const Common::FSList &fslist, const GameFilenamePattern *gfp, const MD5Table *md5Entry, DetectorResult &dr) { dr.language = md5Entry->language; dr.extra = md5Entry->extra; // Compute the precise game settings using gameVariantsTable. for (const GameSettings *g = gameVariantsTable; g->gameid; ++g) { if (g->gameid[0] == 0 || !scumm_stricmp(md5Entry->gameid, g->gameid)) { // The gameid either matches, or is empty. The latter indicates // a generic entry, currently used for some generic HE settings. if (g->variant == 0 || !scumm_stricmp(md5Entry->variant, g->variant)) { // Perfect match found, use it and stop the loop dr.game = *g; dr.game.gameid = md5Entry->gameid; // Set the platform value. The value from the MD5 record has // highest priority; if missing (i.e. set to unknown) we try // to use that from the filename pattern record instead. if (md5Entry->platform != Common::kPlatformUnknown) { dr.game.platform = md5Entry->platform; } else if (gfp->platform != Common::kPlatformUnknown) { dr.game.platform = gfp->platform; } // HACK: Special case to distinguish the V1 demo from the full version // (since they have identical MD5): if (dr.game.id == GID_MANIAC && !strcmp(gfp->pattern, "%02d.MAN")) { dr.extra = "V1 Demo"; } // HACK: If 'Demo' occurs in the extra string, set the GF_DEMO flag, // required by some game demos (e.g. Dig, FT and COMI). if (dr.extra && strstr(dr.extra, "Demo")) { dr.game.features |= GF_DEMO; } // HACK: Try to detect languages for translated games if (dr.language == UNK_LANG) { dr.language = detectLanguage(fslist, dr.game.id); } break; } } } }
int main(int argc, char *argv[]) { const char *dataPath = "DATA"; const char *savePath = "."; const char *levelNum = "0"; char dataPathBuffer[256]; char savePathBuffer[256]; for (int i = 1; i < argc; ++i) { bool opt = false; if (strlen(argv[i]) >= 2) { opt |= parseOption(argv[i], "datapath=", &dataPath); opt |= parseOption(argv[i], "savepath=", &savePath); opt |= parseOption(argv[i], "levelnum=", &levelNum); } if (!opt) { printf(USAGE, argv[0]); return 0; } } #ifdef GCW0 debug(DBG_INFO,"Software version: %s",Game::_version); if(argc<=1){ debug(DBG_INFO, "No arguments given"); char basepath[256]; strcpy(basepath, getenv("HOME")); mkdir(basepath, 0777); strcat(basepath, "/.REminiscence"); strcpy(dataPathBuffer,basepath); strcpy(savePathBuffer,basepath); strcat(dataPathBuffer, "/data"); strcat(savePathBuffer, "/save"); //create directory if they do not exist... mkdir(basepath, 0777); mkdir(savePathBuffer, 0777); mkdir(dataPathBuffer, 0777); dataPath=dataPathBuffer; savePath=savePathBuffer; } #endif g_debugMask = DBG_INFO; // DBG_CUT | DBG_VIDEO | DBG_RES | DBG_MENU | DBG_PGE | DBG_GAME | DBG_UNPACK | DBG_COL | DBG_MOD | DBG_SFX | DBG_FILE; FileSystem fs(dataPath); SystemStub *stub = SystemStub_SDL_create(); const int version = detectVersion(&fs); if (version == -1) { #ifdef GCW0 //display an instruction screen stub->init("help", Video::GAMESCREEN_W, Video::GAMESCREEN_H,new Config()); stub->setPalette(_instr_data_pal,256); stub->copyRect(0, 0, Video::GAMESCREEN_W, Video::GAMESCREEN_H, _instr_data_map, 256); stub->updateScreen(0); while (!stub->_pi.quit) { stub->processEvents(); if (stub->_pi.enter) { stub->_pi.enter = false; break; } stub->sleep(100); } delete stub; #endif error("Unable to find data files, check that all required files are present"); return -1; } Language language = detectLanguage(&fs); Game *g = new Game(stub, &fs, savePath, atoi(levelNum), (ResourceType)version, language); g->run(); delete g; delete stub; return 0; }
static void detectGames(const Common::FSList &fslist, Common::List<DetectorResult> &results, const char *gameid) { DescMap fileMD5Map; DetectorResult dr; // Dive one level down since mac indy3/loom has its files split into directories. See Bug #1438631 composeFileHashMap(fslist, fileMD5Map, 2, directoryGlobs); // Iterate over all filename patterns. for (const GameFilenamePattern *gfp = gameFilenamesTable; gfp->gameid; ++gfp) { // If a gameid was specified, we only try to detect that specific game, // so we can just skip over everything with a differing gameid. if (gameid && scumm_stricmp(gameid, gfp->gameid)) continue; // Generate the detectname corresponding to the gfp. If the file doesn't // exist in the directory we are looking at, we can skip to the next // one immediately. Common::String file(generateFilenameForDetection(gfp->pattern, gfp->genMethod)); if (!fileMD5Map.contains(file)) continue; // Reset the DetectorResult variable dr.fp.pattern = gfp->pattern; dr.fp.genMethod = gfp->genMethod; dr.game.gameid = 0; dr.language = gfp->language; dr.md5.clear(); dr.extra = 0; // ____ _ _ // | _ \ __ _ _ __| |_ / | // | |_) / _` | '__| __| | | // | __/ (_| | | | |_ | | // |_| \__,_|_| \__| |_| // // PART 1: Trying to find an exact match using MD5. // // // Background: We found a valid detection file. Check if its MD5 // checksum occurs in our MD5 table. If it does, try to use that // to find an exact match. // // We only do that if the MD5 hadn't already been computed (since // we may look at some detection files multiple times). // DetectorDesc &d = fileMD5Map[file]; if (d.md5.empty()) { Common::SeekableReadStream *tmp = 0; bool isDiskImg = (file.hasSuffix(".d64") || file.hasSuffix(".dsk") || file.hasSuffix(".prg")); if (isDiskImg) { tmp = openDiskImage(d.node, gfp); debug(2, "Falling back to disk-based detection"); } else { tmp = d.node.createReadStream(); } Common::String md5str; if (tmp) md5str = computeStreamMD5AsString(*tmp, kMD5FileSizeLimit); if (!md5str.empty()) { d.md5 = md5str; d.md5Entry = findInMD5Table(md5str.c_str()); dr.md5 = d.md5; if (d.md5Entry) { // Exact match found. Compute the precise game settings. computeGameSettingsFromMD5(fslist, gfp, d.md5Entry, dr); // Print some debug info int filesize = tmp->size(); if (d.md5Entry->filesize != filesize) debug(1, "SCUMM detector found matching file '%s' with MD5 %s, size %d\n", file.c_str(), md5str.c_str(), filesize); // Sanity check: We *should* have found a matching gameid / variant at this point. // If not, then there's a bug in our data tables... assert(dr.game.gameid != 0); // Add it to the list of detected games results.push_back(dr); } } if (isDiskImg) closeDiskImage((ScummDiskImage*)tmp); delete tmp; } // If an exact match for this file has already been found, don't bother // looking at it anymore. if (d.md5Entry) continue; // ____ _ ____ // | _ \ __ _ _ __| |_ |___ \ * // | |_) / _` | '__| __| __) | // | __/ (_| | | | |_ / __/ // |_| \__,_|_| \__| |_____| // // PART 2: Fuzzy matching for files with unknown MD5. // // We loop over the game variants matching the gameid associated to // the gfp record. We then try to decide for each whether it could be // appropriate or not. dr.md5 = d.md5; for (const GameSettings *g = gameVariantsTable; g->gameid; ++g) { // Skip over entries with a different gameid. if (g->gameid[0] == 0 || scumm_stricmp(gfp->gameid, g->gameid)) continue; dr.game = *g; dr.extra = g->variant; // FIXME: We (ab)use 'variant' for the 'extra' description for now. if (gfp->platform != Common::kPlatformUnknown) dr.game.platform = gfp->platform; // If a variant has been specified, use that! if (gfp->variant) { if (!scumm_stricmp(gfp->variant, g->variant)) { // perfect match found results.push_back(dr); break; } continue; } // HACK: Perhaps it is some modified translation? dr.language = detectLanguage(fslist, g->id); // Add the game/variant to the candidates list if it is consistent // with the file(s) we are seeing. if (testGame(g, fileMD5Map, file)) results.push_back(dr); } } }