diff --git a/src/doc/oiiotool.rst b/src/doc/oiiotool.rst index 0d2f515c6c..ca45f609a9 100644 --- a/src/doc/oiiotool.rst +++ b/src/doc/oiiotool.rst @@ -163,7 +163,9 @@ contents of an expression may be any of: information from when the file was read from disk. * `STATS` : a multi-line string containing the image statistics that would be printed with `oiiotool -stats`. - + * `IS_CONSTANT`: metadata to check if the image pixels are of constant color, returns 1 if true, and 0 if false. + * `IS_BLACK`: metadata to check if the image pixels are all black, a subset of IS_CONSTANT. Also returns 1 if true, and 0 if false. + * *imagename.'metadata'* If the metadata name is not a "C identifier" (initial letter followed by diff --git a/src/oiiotool/expressions.cpp b/src/oiiotool/expressions.cpp index cd4f5128ed..113dd8d242 100644 --- a/src/oiiotool/expressions.cpp +++ b/src/oiiotool/expressions.cpp @@ -317,6 +317,28 @@ Oiiotool::express_parse_atom(const string_view expr, string_view& s, result = out.str(); if (result.size() && result.back() == '\n') result.pop_back(); + } else if (metadata == "IS_CONSTANT") { + std::vector color((*img)(0, 0).nchannels()); + if (ImageBufAlgo::isConstantColor((*img)(0, 0), 0.0f, color)) { + result = "1"; + } else { + result = "0"; + } + } else if (metadata == "IS_BLACK") { + std::vector color((*img)(0, 0).nchannels()); + // Check constant first to guard against false positive average of 0 with negative values i.e. -2, 1, 1 + if (ImageBufAlgo::isConstantColor((*img)(0, 0), 0.0f, color)) { + // trusting that the constantcolor check means all channels have the same value, so we only check the first channel + if (color[0] == 0.0f) { + result = "1"; + } else { + result = "0"; + } + } else { + // Not even constant color case -> We don't want those to count as black frames. + result = "0"; + } + } else if (using_bracket) { // For the TOP[meta] syntax, if the metadata doesn't exist, // return the empty string, and do not make an error. diff --git a/testsuite/oiiotool-control/ref/out.txt b/testsuite/oiiotool-control/ref/out.txt index b4514c0e28..8bddaed47d 100644 --- a/testsuite/oiiotool-control/ref/out.txt +++ b/testsuite/oiiotool-control/ref/out.txt @@ -326,6 +326,10 @@ TOP = ../common/grid.tif, BOTTOM = ../common/tahoe-tiny.tif Stack holds [1] = ../common/tahoe-small.tif filename=../common/tahoe-tiny.tif file_extension=.tif file_noextension=../common/tahoe-tiny MINCOLOR=0,0,0 MAXCOLOR=0.745098,1,1 AVGCOLOR=0.101942,0.216695,0.425293 +Testing expressions IS_BLACK, IS_CONSTANT: + grey is-black? 0 is-constant? 1 + black is-black? 1 is-constant? 1 + gradient is-black? 0 is-constant? 0 Testing NIMAGES: 0 1 diff --git a/testsuite/oiiotool-control/run.py b/testsuite/oiiotool-control/run.py index 79eee9038d..5e02472c3b 100755 --- a/testsuite/oiiotool-control/run.py +++ b/testsuite/oiiotool-control/run.py @@ -183,6 +183,14 @@ "--echo \"filename={TOP.filename} file_extension={TOP.file_extension} file_noextension={TOP.file_noextension}\" " + "--echo \"MINCOLOR={TOP.MINCOLOR} MAXCOLOR={TOP.MAXCOLOR} AVGCOLOR={TOP.AVGCOLOR}\"") +command += oiiotool ("--echo \"Testing expressions IS_BLACK, IS_CONSTANT:\" " + + "--pattern:type=uint16 constant:color=0.5,0.5,0.5 4x4 3 " + + "--echo \" grey is-black? {TOP.IS_BLACK} is-constant? {TOP.IS_CONSTANT}\" " + + "--pattern:type=uint16 constant:color=0,0,0 4x4 3 " + + "--echo \" black is-black? {TOP.IS_BLACK} is-constant? {TOP.IS_CONSTANT}\" " + + "--pattern:type=uint16 fill:left=0,0,0:right=1,1,1 4x4 3 " + + "--echo \" gradient is-black? {TOP.IS_BLACK} is-constant? {TOP.IS_CONSTANT}\" " + ) command += oiiotool ( "--echo \"Testing NIMAGES:\" " + "--echo \" {NIMAGES}\" " +