ImageInput * ImageInput::create (const std::string &filename, bool do_open, const std::string &plugin_searchpath) { if (filename.empty()) { // Can't even guess if no filename given pvt::error ("ImageInput::create() called with no filename"); return NULL; } // Extract the file extension from the filename (without the leading dot) std::string format = Filesystem::extension (filename, false); if (format.empty()) { // If the file had no extension, maybe it was itself the format name format = filename; } ImageInput::Creator create_function = NULL; { // scope the lock: recursive_lock_guard lock (imageio_mutex); // Ensure thread safety // See if it's already in the table. If not, scan all plugins we can // find to populate the table. Strutil::to_lower (format); InputPluginMap::const_iterator found = input_formats.find (format); if (found == input_formats.end()) { catalog_all_plugins (plugin_searchpath.size() ? plugin_searchpath : pvt::plugin_searchpath.string()); found = input_formats.find (format); } if (found != input_formats.end()) create_function = found->second; } // Remember which prototypes we've already tried, so we don't double dip. std::vector<ImageInput::Creator> formats_tried; std::string specific_error; if (create_function) { if (filename != format) { // If given a full filename, double-check that our guess // based on the extension actually works. You never know // when somebody will have an incorrectly-named file, let's // deal with it robustly. formats_tried.push_back (create_function); ImageInput *in = (ImageInput *)create_function(); if (! do_open && in && in->valid_file(filename)) { // Special case: we don't need to return the file // already opened, and this ImageInput says that the // file is the right type. return in; } ImageSpec tmpspec; bool ok = in && in->open (filename, tmpspec); if (ok) { // It worked if (! do_open) in->close (); return in; } else { // Oops, it failed. Apparently, this file can't be // opened with this II. Clear create_function to force // the code below to check every plugin we know. create_function = NULL; if (in) specific_error = in->geterror(); } delete in; } } if (! create_function) { // If a plugin can't be found that was explicitly designated for // this extension, then just try every one we find and see if // any will open the file. Pass it a configuration request that // includes a "nowait" option so that it returns immediately if // it's a plugin that might wait for an event, like a socket that // doesn't yet exist). ImageSpec config; config.attribute ("nowait", (int)1); recursive_lock_guard lock (imageio_mutex); // Ensure thread safety for (InputPluginMap::const_iterator plugin = input_formats.begin(); plugin != input_formats.end(); ++plugin) { // If we already tried this create function, don't do it again if (std::find (formats_tried.begin(), formats_tried.end(), plugin->second) != formats_tried.end()) continue; formats_tried.push_back (plugin->second); // remember ImageSpec tmpspec; ImageInput *in = NULL; try { in = plugin->second(); } catch (...) { // Safety in case the ctr throws an exception } if (! in) continue; if (! do_open && ! in->valid_file(filename)) { // Since we didn't need to open it, we just checked whether // it was a valid file, and it's not. Try the next one. delete in; continue; } // We either need to open it, or we already know it appears // to be a file of the right type. bool ok = in->open(filename, tmpspec, config); if (ok) { if (! do_open) in->close (); return in; } delete in; } } if (create_function == NULL) { recursive_lock_guard lock (imageio_mutex); // Ensure thread safety if (input_formats.empty()) { // This error is so fundamental, we echo it to stderr in // case the app is too dumb to do so. const char *msg = "ImageInput::create() could not find any ImageInput plugins!\n" " Perhaps you need to set OIIO_LIBRARY_PATH.\n"; fprintf (stderr, "%s", msg); pvt::error ("%s", msg); } else if (! specific_error.empty()) { // Pass along any specific error message we got from our // best guess of the format. pvt::error ("%s", specific_error); } else if (Filesystem::exists (filename)) pvt::error ("OpenImageIO could not find a format reader for \"%s\". " "Is it a file format that OpenImageIO doesn't know about?\n", filename.c_str()); else pvt::error ("Image \"%s\" does not exist. Also, it is not the name of an image format that OpenImageIO recognizes.\n", filename.c_str()); return NULL; } return (ImageInput *) create_function(); }