Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api(IB)!: Add span based ImageBuf methods for getpixel/setpixel #4426

Merged
merged 1 commit into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

cmake_minimum_required (VERSION 3.15)

set (OpenImageIO_VERSION "2.6.6.0")
set (OpenImageIO_VERSION "2.6.7.0")
set (OpenImageIO_VERSION_OVERRIDE "" CACHE STRING
"Version override (use with caution)!")
mark_as_advanced (OpenImageIO_VERSION_OVERRIDE)
Expand Down
14 changes: 8 additions & 6 deletions src/doc/imagebuf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,10 @@ Getting and setting pixel values
.. doxygenfunction:: OIIO::ImageBuf::getchannel
.. doxygenfunction:: OIIO::ImageBuf::getpixel(int x, int y, int z, float *pixel, int maxchannels = 1000, WrapMode wrap = WrapBlack) const

.. doxygenfunction:: OIIO::ImageBuf::interppixel
.. doxygenfunction:: OIIO::ImageBuf::interppixel_bicubic
.. doxygenfunction:: OIIO::ImageBuf::interppixel_NDC
.. doxygenfunction:: OIIO::ImageBuf::interppixel_bicubic_NDC
.. doxygenfunction:: OIIO::ImageBuf::interppixel(float, float, span<float>, WrapMode) const
.. doxygenfunction:: OIIO::ImageBuf::interppixel_bicubic(float, float, span<float>, WrapMode) const
.. doxygenfunction:: OIIO::ImageBuf::interppixel_NDC(float, float, span<float>, WrapMode) const
.. doxygenfunction:: OIIO::ImageBuf::interppixel_bicubic_NDC(float, float, span<float>, WrapMode) const

.. doxygenfunction:: OIIO::ImageBuf::setpixel(int x, int y, int z, cspan<float> pixel)
.. doxygenfunction:: OIIO::ImageBuf::setpixel(int i, cspan<float> pixel)
Expand All @@ -175,8 +175,10 @@ Getting and setting pixel values

**Getting and setting regions of pixels -- fast**

.. doxygenfunction:: OIIO::ImageBuf::get_pixels
.. doxygenfunction:: OIIO::ImageBuf::set_pixels
.. doxygenfunction:: OIIO::ImageBuf::get_pixels(ROI, span<T>, stride_t, stride_t, stride_t) const
.. doxygenfunction:: OIIO::ImageBuf::get_pixels(ROI, span<T>, T*, stride_t, stride_t, stride_t) const
.. doxygenfunction:: OIIO::ImageBuf::set_pixels(ROI, span<T>, stride_t, stride_t, stride_t)
.. doxygenfunction:: OIIO::ImageBuf::set_pixels(ROI, span<T>, const T*, stride_t, stride_t, stride_t)



Expand Down
259 changes: 215 additions & 44 deletions src/include/OpenImageIO/imagebuf.h

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions src/include/OpenImageIO/imageio.h
Original file line number Diff line number Diff line change
Expand Up @@ -3370,6 +3370,19 @@ OIIO_API bool copy_image (int nchannels, int width, int height, int depth,
void *dst, stride_t dst_xstride,
stride_t dst_ystride, stride_t dst_zstride);

/// Helper: manufacture a span given an image pointer, format, size, and
/// strides. Use with caution! This is making a lot of assumptions that the
/// data pointer really does point to memory that's ok to access according to
/// the sizes and strides you give.
OIIO_API span<std::byte>
span_from_buffer(void* data, TypeDesc format, int nchannels, int width,
int height, int depth, stride_t xstride = AutoStride, stride_t ystride = AutoStride,
stride_t zstride = AutoStride);
OIIO_API cspan<std::byte>
cspan_from_buffer(const void* data, TypeDesc format, int nchannels, int width,
int height, int depth, stride_t xstride = AutoStride, stride_t ystride = AutoStride,
stride_t zstride = AutoStride);


// All the wrap_foo functions implement a wrap mode, wherein coord is
// altered to be origin <= coord < origin+width. The return value
Expand Down
29 changes: 29 additions & 0 deletions src/include/OpenImageIO/span.h
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,35 @@ spanzero(span<T> dst, size_t offset = 0, size_t n = size_t(-1))
}



/// Does the byte span `query` lie entirely within the safe `bounds` span?
inline bool
span_within(cspan<std::byte> bounds, cspan<std::byte> query)
{
return query.data() >= bounds.data()
&& query.data() + query.size() <= bounds.data() + bounds.size();
}



/// Verify the `ptr[0..len-1]` lies entirely within the given span `s`, which
/// does not need to be the same data type. Return true if that is the case,
/// false if it extends beyond the safe limits fo the span.
template<typename SpanType, typename PtrType>
inline bool
check_span(span<SpanType> s, const PtrType* ptr, size_t len = 1)
{
return span_within(as_bytes(s), as_bytes(make_cspan(ptr, len)));
}



/// OIIO_ALLOCASPAN is used to allocate smallish amount of memory on the
/// stack, equivalent of C99 type var_name[size], and then return a span
/// encompassing it.
#define OIIO_ALLOCA_SPAN(type, size) span<type>(OIIO_ALLOCA(type, size), size)


OIIO_NAMESPACE_END


Expand Down
2 changes: 1 addition & 1 deletion src/iv/imageviewer.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class IvImage final : public ImageBuf {
/// color space correction when indicated.
void pixel_transform(bool srgb_to_linear, int color_mode, int channel);

bool get_pixels(ROI roi, TypeDesc format, void* result)
bool get_pixels(ROI roi, TypeDesc format, span<std::byte> result)
{
if (m_corrected_image.localpixels())
return m_corrected_image.get_pixels(roi, format, result);
Expand Down
15 changes: 9 additions & 6 deletions src/iv/ivgl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -785,9 +785,10 @@ IvGL::paint_pixelview()
m_viewer.current_color_mode());
}

void* zoombuffer = OIIO_ALLOCA(char, (xend - xbegin) * (yend - ybegin)
* nchannels
* spec.channel_bytes());
auto zoombuffer = OIIO_ALLOCA_SPAN(std::byte,
(xend - xbegin) * (yend - ybegin)
* nchannels
* spec.channel_bytes());
if (!m_use_shaders) {
img->get_pixels(ROI(spec.x + xbegin, spec.x + xend, spec.y + ybegin,
spec.y + yend),
Expand All @@ -805,7 +806,7 @@ IvGL::paint_pixelview()
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, m_pixelview_tex);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, xend - xbegin, yend - ybegin,
glformat, gltype, zoombuffer);
glformat, gltype, zoombuffer.data());
print_error("After tsi2d");
} else {
smin = -1;
Expand Down Expand Up @@ -1527,12 +1528,14 @@ IvGL::load_texture(int x, int y, int width, int height)
// may not be resident at once.
if (!m_use_shaders) {
m_current_image->get_pixels(ROI(x, x + width, y, y + height),
spec.format, &m_tex_buffer[0]);
spec.format,
as_writable_bytes(make_span(m_tex_buffer)));
} else {
m_current_image->get_pixels(ROI(x, x + width, y, y + height, 0, 1,
m_viewer.current_channel(),
m_viewer.current_channel() + nchannels),
spec.format, &m_tex_buffer[0]);
spec.format,
as_writable_bytes(make_span(m_tex_buffer)));
}

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pbo_objects[m_last_pbo_used]);
Expand Down
Loading
Loading