@@ -3418,6 +3418,25 @@ get_extension_map()
34183418OIIO_API bool convert_pixel_values (TypeDesc src_type, const void *src,
34193419 TypeDesc dst_type, void *dst, int n = 1 );
34203420
3421+ // / Helper function: copy values from spans `src` to `dst`, converting between
3422+ // / types as appropriate. Return true if ok, false if it didn't know how to do
3423+ // / the conversion.
3424+ // /
3425+ // / The conversion is of normalized (pixel-like) values -- for example 'UINT8'
3426+ // / 255 will convert to float 1.0 and vice versa, not float 255.0. If you want
3427+ // / a straight C-like data cast conversion (e.g., uint8 255 -> float 255.0),
3428+ // / then you should prefer the un-normalized convert_type() utility function
3429+ // / found in typedesc.h.
3430+ template <typename SrcType, typename DstType>
3431+ bool
3432+ convert_pixel_values (cspan<SrcType> src, span<DstType> dst)
3433+ {
3434+ OIIO_DASSERT (dst.size () >= src.size ());
3435+ return convert_pixel_values (TypeDescFromC_v<SrcType>, src.data (),
3436+ TypeDescFromC_v<DstType>, dst.data (),
3437+ std::min (dst.size (), src.size ()));
3438+ }
3439+
34213440
34223441// / Helper routine for data conversion: Convert an image of nchannels x
34233442// / width x height x depth from src to dst. The src and dst may have
@@ -3436,6 +3455,50 @@ OIIO_API bool convert_image (int nchannels, int width, int height, int depth,
34363455 stride_t dst_xstride, stride_t dst_ystride,
34373456 stride_t dst_zstride);
34383457
3458+ // / Helper routine for data conversion: Convert an image described by
3459+ // / image_span `src` into image_span `dst`, which must be the same dimensions
3460+ // / but possibly differing data type and strides. Clever use of this function
3461+ // / can not only exchange data among different formats (e.g., half to 8-bit
3462+ // / unsigned), but also can copy selective channels, copy subimages, etc.
3463+ // / Return true if ok, false if it didn't know how to do the conversion.
3464+ template <typename SrcType, typename DstType>
3465+ bool
3466+ convert_image (image_span<SrcType> src, image_span<DstType> dst)
3467+ {
3468+ // For now, just implement by wrapping the pointer-based version.
3469+ OIIO_DASSERT (src.nchannels () == dst.nchannels ()
3470+ && src.width () == dst.width () && src.height () == dst.height ()
3471+ && src.depth () == dst.depth ());
3472+ return convert_image (src.nchannels (), src.width (), src.height (),
3473+ src.depth (), src.data (), TypeDescFromC_v<SrcType>,
3474+ src.xstride (), src.ystride (), src.zstride (),
3475+ dst.data (), TypeDescFromC_v<DstType>, dst.xstride (),
3476+ dst.ystride (), dst.zstride ());
3477+ }
3478+
3479+
3480+ // / Helper routine for data conversion: Convert an image described by
3481+ // / image_span `src` into image_span `dst`, which must be the same dimensions
3482+ // / but possibly differing data type and strides. The data types are passed as
3483+ // / `TypeDesc`, and the spans are untyped bytes that provide the dimensions
3484+ // / and memory layout.
3485+ inline bool
3486+ convert_image (image_span<const std::byte> src, TypeDesc src_type,
3487+ image_span<std::byte> dst, TypeDesc dst_type)
3488+ {
3489+ // For now, just implement by wrapping the pointer-based version.
3490+ OIIO_DASSERT (src.nchannels () == dst.nchannels ()
3491+ && src.width () == dst.width () && src.height () == dst.height ()
3492+ && src.depth () == dst.depth ());
3493+ OIIO_DASSERT (src_type.size () == src.chansize ()
3494+ && dst_type.size () == dst.chansize ());
3495+ return convert_image (src.nchannels (), src.width (), src.height (),
3496+ src.depth (), src.data (), src_type, src.xstride (),
3497+ src.ystride (), src.zstride (), dst.data (), dst_type,
3498+ dst.xstride (), dst.ystride (), dst.zstride ());
3499+ }
3500+
3501+
34393502
34403503// / A version of convert_image that will break up big jobs into multiple
34413504// / threads.
@@ -3448,6 +3511,48 @@ OIIO_API bool parallel_convert_image (
34483511 stride_t dst_xstride, stride_t dst_ystride,
34493512 stride_t dst_zstride, int nthreads=0 );
34503513
3514+ // / A version of convert_image that will break up big jobs into multiple
3515+ // / threads. The data types are taken from the spans.
3516+ template <typename SrcType, typename DstType>
3517+ bool
3518+ parallel_convert_image (image_span<SrcType> src, image_span<DstType> dst,
3519+ int nthreads = 0 )
3520+ {
3521+ // For now, just implement by wrapping the pointer-based version.
3522+ OIIO_DASSERT (src.nchannels () == dst.nchannels ()
3523+ && src.width () == dst.width () && src.height () == dst.height ()
3524+ && src.depth () == dst.depth ());
3525+ return parallel_convert_image (src.nchannels (), src.width (), src.height (),
3526+ src.depth (), src.data (),
3527+ TypeDescFromC_v<SrcType>, src.xstride (),
3528+ src.ystride (), src.zstride (), dst.data (),
3529+ TypeDescFromC_v<SrcType>, dst.xstride (),
3530+ dst.ystride (), dst.zstride (), nthreads);
3531+ }
3532+
3533+ // / A version of convert_image that will break up big jobs into multiple
3534+ // / threads. The data types are passed as `TypeDesc`, and the spans are
3535+ // / untyped bytes that provide the dimensions and memory layout.
3536+ inline bool
3537+ parallel_convert_image (image_span<const std::byte> src, TypeDesc src_type,
3538+ image_span<std::byte> dst, TypeDesc dst_type,
3539+ int nthreads = 0 )
3540+ {
3541+ // For now, just implement by wrapping the pointer-based version.
3542+ OIIO_DASSERT (src.nchannels () == dst.nchannels ()
3543+ && src.width () == dst.width () && src.height () == dst.height ()
3544+ && src.depth () == dst.depth ());
3545+ OIIO_DASSERT (src_type.size () == src.chansize ()
3546+ && dst_type.size () == dst.chansize ());
3547+ return parallel_convert_image (src.nchannels (), src.width (), src.height (),
3548+ src.depth (), src.data (),
3549+ src_type, src.xstride (),
3550+ src.ystride (), src.zstride (), dst.data (),
3551+ dst_type, dst.xstride (),
3552+ dst.ystride (), dst.zstride (), nthreads);
3553+ }
3554+
3555+
34513556
34523557// / Add random [-ditheramplitude,ditheramplitude] dither to the color channels
34533558// / of the image. Dither will not be added to the alpha or z channel. The
0 commit comments