Skip to content

Commit 5013879

Browse files
lgritzscott-wilson
authored andcommitted
perf: oiiotool --line --text --point --box speedups (AcademySoftwareFoundation#4518)
These commands, which are intended to alter the top image on the stack, were each allocating and copying an image unnecessarily for each operation. By changing the implementation to the right calls that know it doesn't need to make a copy (already a feature I'd implemented in the OiiotoolOp helper class) greatly speeds them up. --------- Signed-off-by: Larry Gritz <[email protected]> Signed-off-by: Scott Wilson <[email protected]>
1 parent d827050 commit 5013879

File tree

1 file changed

+24
-8
lines changed

1 file changed

+24
-8
lines changed

src/oiiotool/oiiotool.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,18 @@ using pvt::print_info_options;
7676
op(); \
7777
}
7878

79+
// Lke OIIOTOOL_OP, but designate the op as "inplace" -- which means it
80+
// uses the input image itself as the destination.
81+
#define OIIOTOOL_INPLACE_OP(name, ninputs, ...) \
82+
static void action_##name(Oiiotool& ot, cspan<const char*> argv) \
83+
{ \
84+
if (ot.postpone_callback(ninputs, action_##name, argv)) \
85+
return; \
86+
OiiotoolOp op(ot, "-" #name, argv, ninputs, __VA_ARGS__); \
87+
op.inplace(true); \
88+
op(); \
89+
}
90+
7991
// Canned setup for an op that uses one image on the stack.
8092
#define UNARY_IMAGE_OP(name, impl) \
8193
OIIOTOOL_OP(name, 1, [](OiiotoolOp& op, span<ImageBuf*> img) { \
@@ -4940,8 +4952,9 @@ OIIOTOOL_OP(contrast, 1, [&](OiiotoolOp& op, span<ImageBuf*> img) {
49404952

49414953
// --box
49424954
// clang-format off
4943-
OIIOTOOL_OP(box, 1, nullptr, ([&](OiiotoolOp& op, span<ImageBuf*> img) {
4944-
img[0]->copy(*img[1]);
4955+
OIIOTOOL_INPLACE_OP(box, 1, nullptr, ([&](OiiotoolOp& op, span<ImageBuf*> img) {
4956+
OIIO_ASSERT(img[0] == img[1]); // Assume we're operating in-place
4957+
// img[0]->copy(*img[1]); // what we'd do if we weren't in-place
49454958
const ImageSpec& Rspec(img[0]->spec());
49464959
int x1, y1, x2, y2;
49474960
string_view s(op.args(1));
@@ -4963,8 +4976,9 @@ OIIOTOOL_OP(box, 1, nullptr, ([&](OiiotoolOp& op, span<ImageBuf*> img) {
49634976

49644977

49654978
// --line
4966-
OIIOTOOL_OP(line, 1, [&](OiiotoolOp& op, span<ImageBuf*> img) {
4967-
img[0]->copy(*img[1]);
4979+
OIIOTOOL_INPLACE_OP(line, 1, [&](OiiotoolOp& op, span<ImageBuf*> img) {
4980+
OIIO_ASSERT(img[0] == img[1]); // Assume we're operating in-place
4981+
// img[0]->copy(*img[1]); // what we'd do if we weren't in-place
49684982
const ImageSpec& Rspec(img[0]->spec());
49694983
std::vector<int> points;
49704984
Strutil::extract_from_list_string(points, op.args(1));
@@ -4983,8 +4997,9 @@ OIIOTOOL_OP(line, 1, [&](OiiotoolOp& op, span<ImageBuf*> img) {
49834997

49844998

49854999
// --point
4986-
OIIOTOOL_OP(point, 1, [&](OiiotoolOp& op, span<ImageBuf*> img) {
4987-
img[0]->copy(*img[1]);
5000+
OIIOTOOL_INPLACE_OP(point, 1, [&](OiiotoolOp& op, span<ImageBuf*> img) {
5001+
OIIO_ASSERT(img[0] == img[1]); // Assume we're operating in-place
5002+
// img[0]->copy(*img[1]); // what we'd do if we weren't in-place
49885003
const ImageSpec& Rspec(img[0]->spec());
49895004
std::vector<int> points;
49905005
Strutil::extract_from_list_string(points, op.args(1));
@@ -5000,8 +5015,9 @@ OIIOTOOL_OP(point, 1, [&](OiiotoolOp& op, span<ImageBuf*> img) {
50005015

50015016

50025017
// --text
5003-
OIIOTOOL_OP(text, 1, [&](OiiotoolOp& op, span<ImageBuf*> img) {
5004-
img[0]->copy(*img[1]);
5018+
OIIOTOOL_INPLACE_OP(text, 1, [&](OiiotoolOp& op, span<ImageBuf*> img) {
5019+
OIIO_ASSERT(img[0] == img[1]); // Assume we're operating in-place
5020+
// img[0]->copy(*img[1]); // what we'd do if we weren't in-place
50055021
const ImageSpec& Rspec(img[0]->spec());
50065022
int x = op.options().get_int("x", Rspec.x + Rspec.width / 2);
50075023
int y = op.options().get_int("y", Rspec.y + Rspec.height / 2);

0 commit comments

Comments
 (0)