Skip to content

Commit

Permalink
fix(ImageBuf): Fix bug in ImageBuf construction from ptr + neg strides (
Browse files Browse the repository at this point in the history
AcademySoftwareFoundation#4630)

There was a bug in span_from_buffer when strides were negative
(basically, we were subtracting, when adding was correct since those
strides were negative values).

Also added a negative stride test to imagebuf_test.cpp. Embarrassed that
we didn't already have this, since it would have caught the problem.

---------

Signed-off-by: Larry Gritz <lg@larrygritz.com>
  • Loading branch information
lgritz authored Feb 9, 2025
1 parent 66f4ae9 commit f8d9380
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
8 changes: 4 additions & 4 deletions src/libOpenImageIO/imagebuf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,20 +99,20 @@ span_from_buffer(void* data, TypeDesc format, int nchannels, int width,
if (xstride >= 0) {
bufend += xstride * (width - 1);
} else {
bufstart -= xstride * (width - 1);
bufstart += xstride * (width - 1);
}
// Expand to the span range for a whole image plane.
if (ystride >= 0) {
bufend += ystride * (height - 1);
} else {
bufstart -= ystride * (height - 1);
bufstart += ystride * (height - 1);
}
// Expand to the span range for a whole volume.
if (depth > 1 && zstride != 0) {
if (zstride >= 0) {
bufend += zstride * (depth - 1);
} else {
bufstart -= zstride * (depth - 1);
bufstart += zstride * (depth - 1);
}
}
return { bufstart, size_t(bufend - bufstart) };
Expand Down Expand Up @@ -905,7 +905,7 @@ ImageBufImpl::set_bufspan_localpixels(span<std::byte> bufspan,
}
m_bufspan = bufspan;
m_localpixels = (char*)buforigin;
OIIO_DASSERT(check_span(m_bufspan, m_localpixels, spec().format));
OIIO_ASSERT(check_span(m_bufspan, m_localpixels, spec().format));
}


Expand Down
25 changes: 25 additions & 0 deletions src/libOpenImageIO/imagebuf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,31 @@ ImageBuf_test_appbuffer_strided()
}
}
}

// Test negative strides by filling with yellow, backwards
{
ImageBufAlgo::fill(wrapped, cspan<float>(green));
// Use the ImageBuf constructor from a pointer to the last pixel and
// negative strides. But don't include the edge pixels of the original
// buffer.
ImageBuf neg(ImageSpec(res - 2, res - 2, nchans, TypeFloat),
&mem[res - 2][res - 2][0] /* point to last pixel */,
-nchans * sizeof(float) /* negative x stride */,
-res * nchans * sizeof(float) /* negative y stride*/);
const float yellow[nchans] = { 1.0f, 1.0f, 0.0f };
ImageBufAlgo::fill(neg, cspan<float>(yellow));

for (int y = 0; y < res; ++y) {
for (int x = 0; x < res; ++x) {
if (x == 0 || x == res - 1 || y == 0 || y == res - 1)
OIIO_CHECK_ASSERT(make_cspan(mem[y][x], nchans)
== make_cspan(green));
else
OIIO_CHECK_ASSERT(make_cspan(mem[y][x], nchans)
== make_cspan(yellow));
}
}
}
}


Expand Down

0 comments on commit f8d9380

Please sign in to comment.