Skip to content

Commit 364abed

Browse files
authored
fix(iinfo): Better iinfo error handling, especially from --hash (#5168)
Try to bubble up errors, stop processing as soon as an error has occurred, correct return code if a file could not be read properly. Signed-off-by: Larry Gritz <lg@larrygritz.com>
1 parent 3c2e174 commit 364abed

2 files changed

Lines changed: 34 additions & 17 deletions

File tree

src/iinfo/iinfo.cpp

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,15 @@ static bool compute_stats = false;
4141

4242

4343

44-
static void
44+
static bool
4545
print_sha1(ImageInput* input, int subimage, int miplevel)
4646
{
4747
std::string err;
4848
std::string s1 = pvt::compute_sha1(input, subimage, miplevel, err);
49+
if (err.size())
50+
input->errorfmt("{}", err);
4951
OIIO::print(" SHA-1: {}\n", err.size() ? err : s1);
52+
return err.empty();
5053
}
5154

5255

@@ -68,7 +71,7 @@ read_input(const std::string& filename, ImageBuf& img, int subimage = 0,
6871

6972

7073

71-
static void
74+
static bool
7275
print_stats(const std::string& filename, const ImageSpec& originalspec,
7376
int subimage = 0, int miplevel = 0, bool indentmip = false)
7477
{
@@ -77,16 +80,17 @@ print_stats(const std::string& filename, const ImageSpec& originalspec,
7780
ImageBuf input(filename);
7881
if (!read_input(filename, input, subimage, miplevel)) {
7982
// Note: read_input prints an error message if one occurs
80-
return;
83+
return false;
8184
}
8285

8386
std::string err;
8487
if (!pvt::print_stats(std::cout, indent, input, originalspec, ROI(), err)) {
8588
OIIO::print("{}Stats: (unable to compute)\n", indent);
8689
if (err.size())
8790
std::cerr << "Error: " << err << "\n";
88-
return;
91+
return false;
8992
}
93+
return true;
9094
}
9195

9296

@@ -236,20 +240,20 @@ brief_format_name(TypeDesc type, int bits = 0)
236240

237241
// prints basic info (resolution, width, height, depth, channels, data format,
238242
// and format name) about given subimage.
239-
static void
243+
static bool
240244
print_info_subimage(int current_subimage, int max_subimages, ImageSpec& spec,
241245
ImageInput* input, const std::string& filename)
242246
{
243247
if (!input->seek_subimage(current_subimage, 0))
244-
return;
248+
return false;
245249
spec = input->spec(current_subimage);
246250

247251
if (!metamatch.empty()
248252
&& !std::regex_search(
249253
"resolution, width, height, depth, channels, sha-1, stats",
250254
field_re)) {
251255
// nothing to do here
252-
return;
256+
return true;
253257
}
254258

255259
int nmip = 1;
@@ -285,39 +289,41 @@ print_info_subimage(int current_subimage, int max_subimages, ImageSpec& spec,
285289
if (printres && nmip > 1)
286290
OIIO::print("\n");
287291

292+
bool ok = true;
288293
if (compute_sha1
289294
&& (metamatch.empty() || std::regex_search("sha-1", field_re))) {
290295
if (filenameprefix)
291296
OIIO::print("{} : ", filename);
292297
// Before sha-1, be sure to point back to the highest-res MIP level
293298
input->seek_subimage(current_subimage, 0);
294-
print_sha1(input, current_subimage, 0);
299+
if (!print_sha1(input, current_subimage, 0))
300+
ok = false;
295301
}
296302

297303
if (verbose)
298304
print_metadata(spec, filename);
299305

300306
if (compute_stats
301307
&& (metamatch.empty() || std::regex_search("stats", field_re))) {
302-
for (int m = 0; m < nmip; ++m) {
308+
for (int m = 0; m < nmip && ok; ++m) {
303309
ImageSpec mipspec = input->spec_dimensions(current_subimage, m);
304310
if (filenameprefix)
305311
OIIO::print("{} : ", filename);
306312
if (nmip > 1 && (subimages || m == 0)) {
307313
OIIO::print(" MIP {} of {} ({} x {}):\n", m, nmip,
308314
mipspec.width, mipspec.height);
309315
}
310-
print_stats(filename, spec, current_subimage, m, nmip > 1);
316+
if (!print_stats(filename, spec, current_subimage, m, nmip > 1))
317+
ok = false;
311318
}
312319
}
313320

314-
if (!input->seek_subimage(current_subimage, 0))
315-
return;
321+
return input->seek_subimage(current_subimage, 0) && ok;
316322
}
317323

318324

319325

320-
static void
326+
static bool
321327
print_info(const std::string& filename, size_t namefieldlength,
322328
ImageInput* input, ImageSpec& spec, bool verbose, bool sum,
323329
long long& totalsize)
@@ -412,8 +418,11 @@ print_info(const std::string& filename, size_t namefieldlength,
412418
if (!subimages)
413419
num_of_subimages = 1;
414420
for (int i = 0; i < num_of_subimages; ++i) {
415-
print_info_subimage(i, num_of_subimages, spec, input, filename);
421+
if (!print_info_subimage(i, num_of_subimages, spec, input, filename))
422+
return false;
416423
}
424+
425+
return true;
417426
}
418427

419428

@@ -480,7 +489,16 @@ main(int argc, const char* argv[])
480489
continue;
481490
}
482491
ImageSpec spec = in->spec();
483-
print_info(s, longestname, in.get(), spec, verbose, sum, totalsize);
492+
if (!print_info(s, longestname, in.get(), spec, verbose, sum,
493+
totalsize)) {
494+
std::string err;
495+
if (in->has_error())
496+
err = in->geterror();
497+
OIIO::print(std::cerr, "iinfo ERROR: \"{}\" : {}\n", s,
498+
err.size() ? err : std::string("Could not open file."));
499+
returncode = EXIT_FAILURE;
500+
continue;
501+
}
484502
}
485503

486504
if (sum)

testsuite/sgi/ref/out.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,4 @@ src/broken01.sgi : 8 x 2, 1 channel, uint8 sgi
3232
SHA-1: Corrupt RLE data
3333
channel list: Y
3434
compression: "rle"
35-
iinfo ERROR: Could not read src/broken01.sgi:
36-
Corrupt RLE data
35+
iinfo ERROR: "src/broken01.sgi" : Corrupt RLE data

0 commit comments

Comments
 (0)