Skip to content

Commit 04df5bf

Browse files
committed
oiiotool: allow expr IMG[x] syntax to allow user vars as well as img labels
Signed-off-by: Larry Gritz <lg@larrygritz.com>
1 parent b2ec6e8 commit 04df5bf

File tree

3 files changed

+61
-22
lines changed

3 files changed

+61
-22
lines changed

src/doc/oiiotool.rst

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,17 @@ contents of an expression may be any of:
123123
If there is no metadata whose name matches, the expression will not have any
124124
substitution made and an error will be issued.
125125

126-
The *imagename* may be one of: `TOP` (the top or current image), `IMG[i]`
127-
describing the i-th image on the stack (thus `TOP` is a synonym for
128-
`IMG[0]`, the next image on the stack is `IMG[1]`, etc.), or `IMG[name]`
129-
to denote an image named by filename or by label name. Remember that the
130-
positions on the stack (including `TOP`) refer to *at that moment*, with
131-
successive commands changing the contents of the top image.
126+
The *imagename* may be one of:
127+
128+
* `TOP` : the top or current image;
129+
* `IMG[index]` : if `index` evaluates to an integer `i`, the i-th image on
130+
the stack (thus `TOP` is a synonym for `IMG[0]`, the next image on the
131+
stack is `IMG[1]`, etc.);
132+
* `IMG[name]` : an image named by filename or by label name.
133+
134+
Remember that the positions on the stack (including `TOP`) refer to *at that
135+
moment*, with successive commands changing the contents of the top image. If
136+
the
132137

133138
The *metadata* may be any of:
134139

src/oiiotool/expressions.cpp

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -155,28 +155,61 @@ Oiiotool::express_parse_atom(const string_view expr, string_view& s,
155155
if (Strutil::parse_prefix(s, "TOP")) {
156156
img = curimg;
157157
} else if (Strutil::parse_prefix(s, "IMG[")) {
158-
int index = -1;
159-
if (Strutil::parse_int(s, index) && Strutil::parse_char(s, ']')
160-
&& index >= 0 && index <= (int)image_stack.size()) {
161-
if (index == 0)
162-
img = curimg;
163-
else
164-
img = image_stack[image_stack.size() - index];
165-
} else {
166-
string_view name = Strutil::parse_until(s, "]");
167-
auto found = image_labels.find(name);
168-
if (found != image_labels.end())
169-
img = found->second;
170-
else
171-
img = ImageRecRef(new ImageRec(name, imagecache));
172-
Strutil::parse_char(s, ']');
158+
std::string until_bracket = Strutil::parse_until(s, "]");
159+
if (until_bracket.empty() || !Strutil::parse_char(s, ']')) {
160+
express_error(expr, until_bracket,
161+
"malformed IMG[] specification");
162+
result = orig;
163+
return false;
164+
}
165+
auto labelfound = image_labels.find(until_bracket);
166+
if (labelfound != image_labels.end()) {
167+
// Found an image label
168+
img = labelfound->second;
169+
} else if (Strutil::string_is_int(until_bracket)) {
170+
// It's an integer... don't process more quite yet
171+
} else if (Filesystem::exists(until_bracket)) {
172+
// It's the name of an image file
173+
img = ImageRecRef(new ImageRec(until_bracket, imagecache));
174+
}
175+
if (!img) {
176+
// Not a label, int, or file. Evaluate it as an expression.
177+
// Evaluate it as an expression and hope it's an integer or
178+
// the name of an image?
179+
until_bracket = express_impl(until_bracket);
180+
if (Strutil::string_is_int(until_bracket)) {
181+
// Between brackets (including an expanded variable) is an
182+
// integer -- it's an index into the image stack (error if out
183+
// of range).
184+
int index = Strutil::stoi(until_bracket);
185+
if (index >= 0 && index <= (int)image_stack.size()) {
186+
img = (index == 0)
187+
? curimg
188+
: image_stack[image_stack.size() - index];
189+
} else {
190+
express_error(expr, until_bracket,
191+
"out-of-range IMG[] index");
192+
result = orig;
193+
return false;
194+
}
195+
} else if (Filesystem::exists(until_bracket)) {
196+
// It's the name of an image file
197+
img = ImageRecRef(new ImageRec(until_bracket, imagecache));
198+
}
199+
}
200+
if (!img || img->has_error()) {
201+
express_error(expr, until_bracket, "not a valid image");
202+
result = orig;
203+
return false;
173204
}
174205
}
175-
if (!img.get()) {
206+
if (!img || img->has_error()) {
176207
express_error(expr, s, "not a valid image");
177208
result = orig;
178209
return false;
179210
}
211+
OIIO_ASSERT(img);
212+
img->read();
180213
bool using_bracket = false;
181214
if (Strutil::parse_char(s, '[')) {
182215
using_bracket = true;

testsuite/oiiotool-control/ref/out.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ Constant: No
260260
Monochrome: No
261261

262262
Stack holds [0] = ../common/tahoe-small.tif, [1] = ../common/tahoe-tiny.tif
263+
Stack holds [1] = ../common/tahoe-tiny.tif
263264
filename=../common/tahoe-tiny.tif file_extension=.tif file_noextension=../common/tahoe-tiny
264265
MINCOLOR=0,0,0 MAXCOLOR=0.745098,1,1 AVGCOLOR=0.101942,0.216695,0.425293
265266
Testing NIMAGES:

0 commit comments

Comments
 (0)