Skip to content

Commit

Permalink
Allow env OPENIMAGEIO_OPTIONS to set global OIIO::attribute()
Browse files Browse the repository at this point in the history
Akin to how we have `OPENIMAGEIO_IMAGECACHE_OPTIONS` and
`OPENIMAGEIO_TEXTURE_OPTIONS`.

`OPENIMAGEIO_TEXTURE_OPTIONS` is a comma-separated list of name=val
pairs that upon startup will seed the global options that are usually
set by the OIIO::attribute() call.

Along the way, I beefed up the OptParser to be able to handle both
single and double quotes equally well. That lets you set an option that
is a string, that itself contains quotes.

Also document all of these options -- I realized the PDF docs don't talk
about even the existing env variables.
  • Loading branch information
lgritz committed Jan 2, 2019
1 parent a8e7229 commit 45ac8ef
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 7 deletions.
28 changes: 28 additions & 0 deletions src/doc/imageioapi.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1115,6 +1115,19 @@ \section{Miscellaneous Utilities}

\noindent The following are the recognized attributes:

\apiitem{string options}
\vspace{10pt}
This catch-all is simply a comma-separated list of {\cf name=value}
settings of named options, which will be parsed and individually set.
For example,
\begin{code}
OIIO::attribute ("options", "threads=4,log_times=1");
\end{code}
Note that if an option takes a string value that must itself contain a
comma, it is permissible to enclose the value in either single ({\cf ' '})
or double ({\cf " "}) quotes.
\apiend

\apiitem{int threads}
\vspace{10pt}
\index{threads} \label{sec:attribute:threads}
Expand Down Expand Up @@ -1349,6 +1362,21 @@ \section{Environment variables}
\product at times that it is not convenient to set options individually from
inside the source code.

\apiitem{OPENIMAGEIO_OPTIONS}
\NEW % 2.0
Allows you to seed the global \product-wide options.

The value of the environment variable should be a comma-separated list of
\emph{name=value} settings. If a value is a string that itself needs to
contain commas, it may be enclosed in single or double quotes.

Upon startup, the contents of this environment variable will be passed
to a call to:
\begin{code}
OIIO::attribute ("options", value);
\end{code}
\apiend

\apiitem{OPENIMAGEIO_IMAGECACHE_OPTIONS}
Allows you to seed the options for any \ImageCache created.

Expand Down
19 changes: 12 additions & 7 deletions src/include/OpenImageIO/optparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ optparse1(C& system, const std::string& opt)
// otherwise treat it as a string

// trim surrounding double quotes
if (value.size() >= 2 && value[0] == '\"'
&& value[value.size() - 1] == '\"')
if (value.size() >= 2 && (value[0] == '\"' || value[0] == '\'')
&& value[value.size() - 1] == value[0])
value = std::string(value, 1, value.size() - 2);

return system.attribute(name.c_str(), value.c_str());
return system.attribute(name, value);
}


Expand All @@ -98,12 +98,17 @@ optparser(C& system, const std::string& optstring)
size_t pos = 0;
while (pos < len) {
std::string opt;
bool inquote = false;
char inquote = 0;
while (pos < len) {
unsigned char c = optstring[pos];
if (c == '\"') {
// Hit a double quote -- toggle "inquote" and add the quote
inquote = !inquote;
if (c == inquote) {
// Ending a quote
inquote = 0;
opt += c;
++pos;
} else if (c == '\"' || c == '\'') {
// Found a quote
inquote = c;
opt += c;
++pos;
} else if (c == ',' && !inquote) {
Expand Down
26 changes: 26 additions & 0 deletions src/libOpenImageIO/imageio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <OpenImageIO/fmath.h>
#include <OpenImageIO/hash.h>
#include <OpenImageIO/imageio.h>
#include <OpenImageIO/optparser.h>
#include <OpenImageIO/parallel.h>
#include <OpenImageIO/strutil.h>
#include <OpenImageIO/sysutil.h>
Expand Down Expand Up @@ -143,6 +144,27 @@ class TimingLog {
};
static TimingLog timing_log;



// Pipe-fitting class to set global options, for the sake of optparser.
struct GlobalOptSetter {
public:
template<typename T> bool attribute(string_view name, T val) const
{
return OIIO::attribute(name, val);
}
};


// Trick to force get the "OPENIMAGEIO_OPTIONS" env var on startup.
bool force_global_opts = []() {
auto options = Sysutil::getenv("OPENIMAGEIO_OPTIONS");
// std::cout << "OPTIONS: '" << options << "'\n";
if (!options.empty())
attribute("options", options);
return true;
}();

} // namespace


Expand Down Expand Up @@ -283,6 +305,10 @@ pvt::log_time(string_view key, const Timer& timer)
bool
attribute(string_view name, TypeDesc type, const void* val)
{
if (name == "options" && type == TypeDesc::STRING) {
GlobalOptSetter gos;
return optparser(gos, *(const char**)val);
}
if (name == "threads" && type == TypeInt) {
int ot = Imath::clamp(*(const int*)val, 0, maxthreads);
if (ot == 0)
Expand Down

0 comments on commit 45ac8ef

Please sign in to comment.