Skip to content

Commit b8ffc12

Browse files
authored
api: add image_span, deprecate image_view (#4703)
* `image_span<T,Rank>` is a 2D-to-4D bounded span with byte-measured strides (describing data layout with dimensions for channel, x, y, z) for us to have future APIs deal with bounded+strided regions rather than YOLOing raw pointers. Among other advantages, image_span will have robust bounds checking in debug builds. It also simplifies interfaces to pass a single image_span that encapsulates everything about an up-to-4D data layout, rather than needing to pass a long list of individual pointers, sizes, and strides. * I've templated image_span on Rank, but default to Rank=4 and am using that version only in practice. The templating by rank allows future expansion to describe one scanline (rank 2) or 2D image plane (Rank 3) if we want to do so for certain API calls, but I'm not sure yet whether to bother with that, so for now, the ability to template by Rank is just flexibility for the future. * Add image_span based versions of copy_image(), contiguize(), convert_pixel_values(), convert_image(), and parallel_convert_image() utilities. I added tests and benchmarks to verify their correctness and that they have similar performance to the pointer based versions. * Deprecate image_view, which we did not ever use internally to OIIO or in its APIs. But since we published the headers, there's a chance it's used downstream and would be unwise to change its behavior or data layout. The new image_span is what we will use moving forward so that we are free to modify it and start with a fresh slate. Keeping the definition/header for now, but marking it with a deprecation warning. --------- Signed-off-by: Larry Gritz <[email protected]>
1 parent 88c3cbe commit b8ffc12

File tree

11 files changed

+1124
-73
lines changed

11 files changed

+1124
-73
lines changed

src/doc/imageioapi.rst

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ Efficient unique strings: ``ustring``
9595
9696
.. _sec-span:
9797

98-
Non-owning array views: ``span`` / ``cspan``
99-
============================================
98+
Non-owning contiguous array views: ``span`` / ``cspan``
99+
=======================================================
100100

101101
.. doxygenclass:: OIIO::span
102102
:members:
@@ -111,6 +111,18 @@ Additionally, there is a convenience template:
111111
|
112112
113113

114+
.. _sec-span:
115+
116+
Non-owning image array views: ``image_span``
117+
============================================
118+
119+
.. doxygenclass:: OIIO::image_span
120+
:members:
121+
122+
123+
|
124+
125+
114126

115127
.. _sec-ROI:
116128

src/include/OpenImageIO/fmath.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ scaled_conversion(const S& src, F scale, F min, F max)
757757
template<typename S, typename D>
758758
void convert_type (const S *src, D *dst, size_t n, D _min, D _max)
759759
{
760-
if (std::is_same<S,D>::value) {
760+
if constexpr (std::is_same<S,D>::value) {
761761
// They must be the same type. Just memcpy.
762762
memcpy (dst, src, n*sizeof(D));
763763
return;
@@ -968,6 +968,25 @@ inline void convert_type (const S *src, D *dst, size_t n)
968968

969969

970970

971+
/// Copy (type convert) consecutive values from the cspan `src` holding data
972+
/// of type S into the span `dst` holding the same number of elements of data
973+
/// of type D.
974+
///
975+
/// The conversion is not a simple cast, but correctly remaps the 0.0->1.0
976+
/// range from and to the full positive range of integral types. It's just a
977+
/// straight copy if both types are identical. Optional arguments `min` and
978+
/// `max` can give nonstandard quantizations.
979+
template<typename S, typename D>
980+
void convert_type (cspan<S> src, span<D> dst,
981+
D min = std::numeric_limits<D>::min(),
982+
D max = std::numeric_limits<D>::min())
983+
{
984+
OIIO_DASSERT(src.size() == dst.size());
985+
convert_type(src.data(), dst.data(), std::min(src.size(), dst.size()),
986+
min, max);
987+
}
988+
989+
971990

972991
/// Convert a single value from the type of S to the type of D.
973992
/// The conversion is not a simple cast, but correctly remaps the
@@ -978,7 +997,7 @@ template<typename S, typename D>
978997
inline D
979998
convert_type (const S &src)
980999
{
981-
if (std::is_same<S,D>::value) {
1000+
if constexpr (std::is_same<S,D>::value) {
9821001
// They must be the same type. Just return it.
9831002
return (D)src;
9841003
}

0 commit comments

Comments
 (0)