Skip to content

Commit 068b456

Browse files
committed
api: image_span-ify ImageBuf::set_pixels()
Signed-off-by: Larry Gritz <[email protected]>
1 parent 691acac commit 068b456

File tree

4 files changed

+61
-9
lines changed

4 files changed

+61
-9
lines changed

src/doc/imagebuf.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ Getting and setting pixel values
181181

182182
.. doxygenfunction:: OIIO::ImageBuf::get_pixels(ROI, const image_span<T>&) const
183183
.. doxygenfunction:: OIIO::ImageBuf::get_pixels(ROI, TypeDesc, const image_span<std::byte>&) const
184+
.. doxygenfunction:: OIIO::ImageBuf::set_pixels(ROI, const image_span<T>&)
185+
.. doxygenfunction:: OIIO::ImageBuf::set_pixels(ROI, TypeDesc, const image_span<std::byte>&)
184186

185187
|
186188

src/include/OpenImageIO/imagebuf.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,30 @@ class OIIO_API ImageBuf {
10871087
/// itself. Return true if the operation could be completed, otherwise
10881088
/// return false.
10891089

1090+
/// Set the rectangle of pixels within the ROI to the values in the
1091+
/// `buffer`.
1092+
///
1093+
/// @param roi
1094+
/// The region of interest to copy into. A default
1095+
/// uninitialized ROI means the entire image.
1096+
/// @param buffer
1097+
/// An `image_span` delineating the extent of the safely
1098+
/// accessible memory where the results should be copied from.
1099+
/// @returns
1100+
/// Return true if the operation could be completed,
1101+
/// otherwise return false.
1102+
///
1103+
template<typename T> bool set_pixels(ROI roi, const image_span<T> buffer)
1104+
{
1105+
return set_pixels(roi, TypeDescFromC<T>::value(),
1106+
as_image_span_bytes(buffer));
1107+
}
1108+
1109+
/// Base case of set_pixels: copy from an image_span of generic bytes.
1110+
/// The requested data type is supplied by `format`.
1111+
bool set_pixels(ROI roi, TypeDesc format,
1112+
const image_span<const std::byte>& buffer);
1113+
10901114
/// Set the rectangle of pixels within the ROI to the values in the
10911115
/// `buffer`.
10921116
///

src/libOpenImageIO/imagebuf.cpp

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2773,8 +2773,8 @@ set_pixels_(ImageBuf& buf, ROI roi, const void* data_, stride_t xstride,
27732773

27742774

27752775
bool
2776-
ImageBuf::set_pixels(ROI roi, TypeDesc format, const void* data,
2777-
stride_t xstride, stride_t ystride, stride_t zstride)
2776+
ImageBuf::set_pixels(ROI roi, TypeDesc format,
2777+
const image_span<const std::byte>& buffer)
27782778
{
27792779
if (!initialized()) {
27802780
errorfmt("Cannot set_pixels() on an uninitialized ImageBuf");
@@ -2784,17 +2784,42 @@ ImageBuf::set_pixels(ROI roi, TypeDesc format, const void* data,
27842784
roi = this->roi();
27852785
roi.chend = std::min(roi.chend, nchannels());
27862786

2787-
ImageSpec::auto_stride(xstride, ystride, zstride, format.size(),
2788-
roi.nchannels(), roi.width(), roi.height());
2787+
if (buffer.chanstride() != stride_t(format.size())) {
2788+
errorfmt(
2789+
"set_pixels does not currently support image_span source with non-contiguous channels");
2790+
return false;
2791+
}
2792+
if (size_t(roi.nchannels()) > buffer.nchannels()
2793+
|| size_t(roi.width()) > buffer.width()
2794+
|| size_t(roi.height()) > buffer.height()
2795+
|| size_t(roi.depth()) > buffer.depth()) {
2796+
errorfmt(
2797+
"set_pixels source image_span was not big enough for the specified ROI.");
2798+
return false;
2799+
}
27892800

27902801
bool ok;
27912802
OIIO_DISPATCH_TYPES2(ok, "set_pixels", set_pixels_, spec().format, format,
2792-
*this, roi, data, xstride, ystride, zstride);
2803+
*this, roi, buffer.data(), buffer.xstride(),
2804+
buffer.ystride(), buffer.zstride());
27932805
return ok;
27942806
}
27952807

27962808

27972809

2810+
bool
2811+
ImageBuf::set_pixels(ROI roi, TypeDesc format, const void* data,
2812+
stride_t xstride, stride_t ystride, stride_t zstride)
2813+
{
2814+
image_span<const std::byte> s(reinterpret_cast<const std::byte*>(data),
2815+
roi.nchannels(), roi.width(), roi.height(),
2816+
roi.depth(), format.size(), xstride, ystride,
2817+
zstride);
2818+
return set_pixels(roi, format, s);
2819+
}
2820+
2821+
2822+
27982823
bool
27992824
ImageBuf::set_pixels(ROI roi, TypeDesc format, cspan<std::byte> buffer,
28002825
const void* buforigin, stride_t xstride, stride_t ystride,

src/python/py_imagebuf.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,11 @@ ImageBuf_from_buffer(const py::buffer& buffer)
6868
spec.depth = depth;
6969
spec.full_depth = depth;
7070
ib.reset(spec, InitializePixels::No);
71-
auto bufspan = cspan_from_buffer(info.ptr, format, nchans, width, height,
72-
depth, xstride, ystride, zstride);
73-
ib.set_pixels(get_roi(spec), format, bufspan, nullptr, xstride, ystride,
74-
zstride);
71+
image_span<const std::byte> bufspan(reinterpret_cast<std::byte*>(info.ptr),
72+
nchans, width, height, depth,
73+
format.size(), xstride, ystride,
74+
zstride, format.size());
75+
ib.set_pixels(get_roi(spec), format, bufspan);
7576
return ib;
7677
}
7778

0 commit comments

Comments
 (0)