diff --git a/src/include/OpenImageIO/imageio.h b/src/include/OpenImageIO/imageio.h index 1002d8cf0b..63d3626e7a 100644 --- a/src/include/OpenImageIO/imageio.h +++ b/src/include/OpenImageIO/imageio.h @@ -355,13 +355,26 @@ class OIIO_API ImageSpec { : ImageSpec(roi, TypeDesc(fmt)) {} /// Set the data format, and clear any per-channel format information - /// in `channelformats`. + /// in `channelformats`. Any existing "oiio:BitsPerSample" metadata + /// hints are also cleared and assumed to be the full bits implied by + /// the format. void set_format (TypeDesc fmt) noexcept; + /// Set the data format, and clear any per-channel format information in + /// `channelformats`. If the optional `bits` is supplied, set the + /// "oiio:BitsPerSample" metadata hint, otherwise it is assumed that it is + /// the same as implied by the format and cleared. + void set_format (TypeDesc fmt, int bits) noexcept; + /// Set the data format, and clear any per-channel format information /// in `channelformats`. The `fmt` may be a string such as `"uint8"`, /// or any other type name recognized by the TypeDesc constructor. - void set_format (string_view fmt) noexcept { set_format(TypeDesc(fmt)); } + /// If the optional `bits` is supplied, set the "oiio:BitsPerSample" + /// metadata hint, otherwise it is assumed that it is the same as implied + /// by the format. + void set_format (string_view fmt, int bits = 0) noexcept { + set_format(TypeDesc(fmt), bits); + } /// Sets the `channelnames` to reasonable defaults for the number of /// channels. Specifically, channel names are set to "R", "G", "B," diff --git a/src/libOpenImageIO/formatspec.cpp b/src/libOpenImageIO/formatspec.cpp index 81374b9624..fccc151baa 100644 --- a/src/libOpenImageIO/formatspec.cpp +++ b/src/libOpenImageIO/formatspec.cpp @@ -185,9 +185,34 @@ ImageSpec::ImageSpec(const ROI& roi, TypeDesc format) noexcept void ImageSpec::set_format(TypeDesc fmt) noexcept +{ +#if 1 + set_format(fmt, 0); +#else + // Note: this would preserve backward behavioral compatibility -- no + // opinion on the "oiio:BitsPerSample" hint. + format = fmt; + channelformats.clear(); +#endif +} + + + +void +ImageSpec::set_format(TypeDesc fmt, int bits) noexcept { format = fmt; channelformats.clear(); + if (bits > 0 && bits < int(fmt.size()) * 8) { + // If bits is nonzero, and not already set to the "full" bit width for + // `fmt`, and valid (must be positive and less than the number of bits + // available), set the "oiio:BitsPerSample" metadata. + attribute("oiio:BitsPerSample", bits); + } else { + // No valid bits, or it's not needed -- clear any existing bps + // metadata. + erase_attribute("oiio:BitsPerSample"); + } }