Skip to content

Commit eae19db

Browse files
authored
oiiotool --oiioattrib (#3171)
This new oiiotool command lets you set global OIIO attributes, i.e., making calls to OIIO::attribute(). It allows oiiotool command lines to set some additional OIIO-wide options for which no specific oiiotool command flags could otherwise access.
1 parent e058dc8 commit eae19db

File tree

2 files changed

+95
-2
lines changed

2 files changed

+95
-2
lines changed

src/doc/oiiotool.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,26 @@ output each one to a different file, with names `sub0001.tif`,
884884
command line, for example if you actually have filenames containing curly
885885
braces.
886886

887+
.. option:: --oiioattrib <name> <value>
888+
889+
Adds or replaces a global OpenImageIO attribute with the given *name* to
890+
have the specified *value*.
891+
892+
Optional appended modifiers include:
893+
894+
- `type=` *typename* : Specify the metadata type.
895+
896+
If the optional `type=` specifier is used, that provides an explicit
897+
type for the metadata. If not provided, it will try to infer the type of
898+
the metadata from the value: if the value contains only numerals (with
899+
optional leading minus sign), it will be saved as `int` metadata; if it
900+
also contains a decimal point, it will be saved as `float` metadata;
901+
otherwise, it will be saved as a `string` metadata.
902+
903+
Examples::
904+
905+
oiiotool --oiioattrib debug 1 in.jpg -o out.jpg
906+
887907

888908

889909
:program:`oiiotool` commands: reading and writing images

src/oiiotool/oiiotool.cpp

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,75 @@ set_dataformat(int argc, const char* argv[])
968968

969969

970970

971+
// --oiioattrib
972+
static int
973+
set_oiio_attribute(int argc, const char* argv[])
974+
{
975+
OIIO_DASSERT(argc == 3);
976+
977+
string_view command = ot.express(argv[0]);
978+
string_view attribname = ot.express(argv[1]);
979+
string_view value = ot.express(argv[2]);
980+
auto options = ot.extract_options(command);
981+
TypeDesc type(options["type"].as_string());
982+
983+
// First, handle the cases where we're told what to expect
984+
if (type.basetype == TypeDesc::FLOAT) {
985+
size_t n = type.numelements() * type.aggregate;
986+
std::vector<float> vals(n, 0.0f);
987+
for (size_t i = 0; i < n && value.size(); ++i) {
988+
Strutil::parse_float(value, vals[i]);
989+
Strutil::parse_char(value, ',');
990+
}
991+
OIIO::attribute(attribname, type, vals.data());
992+
return 1;
993+
}
994+
if (type.basetype == TypeDesc::INT) {
995+
size_t n = type.numelements() * type.aggregate;
996+
std::vector<int> vals(n, 0);
997+
for (size_t i = 0; i < n && value.size(); ++i) {
998+
Strutil::parse_int(value, vals[i]);
999+
Strutil::parse_char(value, ',');
1000+
}
1001+
OIIO::attribute(attribname, type, vals.data());
1002+
return 1;
1003+
}
1004+
if (type.basetype == TypeDesc::STRING) {
1005+
size_t n = type.numelements() * type.aggregate;
1006+
std::vector<ustring> vals(n, ustring());
1007+
if (n == 1)
1008+
vals[0] = ustring(value);
1009+
else {
1010+
for (size_t i = 0; i < n && value.size(); ++i) {
1011+
string_view s;
1012+
Strutil::parse_string(value, s);
1013+
vals[i] = ustring(s);
1014+
Strutil::parse_char(value, ',');
1015+
}
1016+
}
1017+
OIIO::attribute(attribname, type, vals.data());
1018+
return 1;
1019+
}
1020+
1021+
if (type == TypeInt
1022+
|| (type == TypeUnknown && Strutil::string_is_int(value))) {
1023+
// Does it seem to be an int, or did the caller explicitly request
1024+
// that it be set as an int?
1025+
return OIIO::attribute(attribname, Strutil::stoi(value));
1026+
} else if (type == TypeFloat
1027+
|| (type == TypeUnknown && Strutil::string_is_float(value))) {
1028+
// Does it seem to be a float, or did the caller explicitly request
1029+
// that it be set as a float?
1030+
return OIIO::attribute(attribname, Strutil::stof(value));
1031+
} else {
1032+
// Otherwise, set it as a string attribute
1033+
return OIIO::attribute(attribname, value);
1034+
}
1035+
return 0;
1036+
}
1037+
1038+
1039+
9711040
static int
9721041
set_string_attribute(int argc, const char* argv[])
9731042
{
@@ -5226,8 +5295,9 @@ command_line_string(int argc, char* argv[], bool sansattrib)
52265295
if (sansattrib) {
52275296
// skip any filtered attributes
52285297
if (!strcmp(argv[i], "--attrib") || !strcmp(argv[i], "-attrib")
5229-
|| !strcmp(argv[i], "--sattrib")
5230-
|| !strcmp(argv[i], "-sattrib")) {
5298+
|| !strcmp(argv[i], "--sattrib") || !strcmp(argv[i], "-sattrib")
5299+
|| !strcmp(argv[i], "--oiioattrib")
5300+
|| !strcmp(argv[i], "-oiioattrib")) {
52315301
i += 2; // also skip the following arguments
52325302
continue;
52335303
}
@@ -5582,6 +5652,9 @@ getargs(int argc, char* argv[])
55825652
.action(set_autotile);
55835653
ap.arg("--metamerge", &ot.metamerge)
55845654
.help("Always merge metadata of all inputs into output");
5655+
ap.arg("--oiioattrib %s:NAME %s:VALUE")
5656+
.help("Sets global OpenImageIO attribute (options: type=...)")
5657+
.action(set_oiio_attribute);
55855658
ap.arg("--nostderr", &ot.nostderr)
55865659
.help("Do not use stderr, output error messages to stdout")
55875660
.hidden();

0 commit comments

Comments
 (0)