fix(ImageBuf): Better errors for nonexistant subimages/mips #4801
+197
−39
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
An important clarification: ImageInput::seek_subimage() returns false
but does not set an error message if the only thing wrong is
requesting a non-existent subimage or miplevel, and similarly,
ImageInput::spec() and spec_dimensions() set an empty spec (easy to
tell by spec.format == TypeUnknown) in that case. All three of these
only set an error message if the reason it couldn't perform the task
because there was actually something wrong with the file or the
I/O. (Put another way, it's common to use these to simply probe which
subimages or mip levels exist, and returning false for "no it doesn't"
isn't really an error, it's expected behavior.)
OK, then.
We weren't always following these rules, sometimes setting
error messages when we shouldn't.
Other times (in different routines) when we didn't set error messages
but should have. And also, there are some downstream places such as
ImageBuf::init_spec() that assumed that seek_subimage / spec /
spec_dimensions set an error message (but they didn't, by design) and
should have raised their own errors when discovering that a requested
subimage or miplevel didn't exist.
Also, there were a couple spots in ImageBuf internals where we tried
to do the right thing, but instead of calling ImageBufImpl::error(),
we called errorfmt(), which didn't exist in ImageBufImpl, and so was
calling the global OIIO::errorfmt(), which therefore was setting the
error on the wrong object entirely. (Fix that by adding an errorfmt
method in ImageBufImpl so that mistake is not possible. Should have
been like that all along.)
All this leads to more consistent error reporting (and not reporting,
in the cases we weren't supposed to), especially for people calling
ImageBuf::read() and ImageBuf::init_spec().