Skip to content
Draft
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
5 changes: 4 additions & 1 deletion src/bmp.imageio/bmpinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include <OpenImageIO/fmath.h>
#include <OpenImageIO/imageio.h>

#include "imageio_pvt.h"

#include "bmp_pvt.h"

OIIO_PLUGIN_NAMESPACE_BEGIN
Expand Down Expand Up @@ -262,7 +264,8 @@ BmpInput::open(const std::string& name, ImageSpec& newspec,
// Default presumption is that a BMP file is meant to look reasonable on a
// display, so assume it's sRGB. This is not really correct -- see the
// comments below.
m_spec.attribute("oiio:ColorSpace", "srgb_rec709_scene");
const bool erase_other_attributes = false;
pvt::set_colorspace_srgb(m_spec, erase_other_attributes);
#if 0
if (m_dib_header.size >= WINDOWS_V4
&& m_dib_header.cs_type == CSType::CalibratedRGB) {
Expand Down
21 changes: 11 additions & 10 deletions src/dds.imageio/ddsinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <OpenImageIO/parallel.h>
#include <OpenImageIO/typedesc.h>

#include "imageio_pvt.h"

#include "dds_pvt.h"
#define BCDEC_IMPLEMENTATION
#include "bcdec.h"
Expand Down Expand Up @@ -828,7 +830,7 @@ DDSInput::seek_subimage(int subimage, int miplevel)
if (bpp != 0)
m_spec.attribute("oiio:BitsPerSample", bpp);

const char* colorspace = nullptr;
bool is_srgb = false;

if (m_dds.fmt.fourCC == DDS_4CC_DX10) {
switch (m_dx10.dxgiFormat) {
Expand All @@ -838,18 +840,17 @@ DDSInput::seek_subimage(int subimage, int miplevel)
case DDS_FORMAT_BC7_UNORM_SRGB:
case DDS_FORMAT_R8G8B8A8_UNORM_SRGB:
case DDS_FORMAT_B8G8R8A8_UNORM_SRGB:
case DDS_FORMAT_B8G8R8X8_UNORM_SRGB:
colorspace = "srgb_rec709_scene";
break;
case DDS_FORMAT_B8G8R8X8_UNORM_SRGB: is_srgb = true; break;
}
}

// linear color space for HDR-ish images
if (colorspace == nullptr
&& (basetype == TypeDesc::HALF || basetype == TypeDesc::FLOAT))
colorspace = "lin_rec709_scene";

m_spec.set_colorspace(colorspace);
if (is_srgb) {
pvt::set_colorspace_srgb(m_spec);
} else if (!is_srgb
&& (basetype == TypeDesc::HALF || basetype == TypeDesc::FLOAT)) {
// linear color space for HDR-ish images
m_spec.set_colorspace("lin_rec709_scene");
}

m_spec.default_channel_names();
// Special case: if a 2-channel DDS RG or YA?
Expand Down
3 changes: 2 additions & 1 deletion src/doc/builtinplugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ tiles.
- Version of the BMP file format
* - ``oiio:ColorSpace``
- string
- currently, it is always ``"sRGB"`` (we presume all BMP files are sRGB)
- currently, it is always ``"srgb_rec709_display"`` or
``"srgb_rec709_scene"`` (we presume all BMP files are sRGB)

**Configuration settings for BMP input**

Expand Down
15 changes: 9 additions & 6 deletions src/doc/imagebufalgo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2849,12 +2849,14 @@ Color space conversion
.. code-tab:: c++

ImageBuf Src ("tahoe.jpg");
ImageBuf Dst = ImageBufAlgo::colorconvert (Src, "sRGB", "acescg", true);
ImageBuf Dst = ImageBufAlgo::colorconvert (Src, "srgb_rec709_scene",
"acescg", true);

.. code-tab:: py

Src = ImageBuf("tahoe.jpg")
Dst = ImageBufAlgo.colorconvert (Src, "sRGB", "acescg", True)
Dst = ImageBufAlgo.colorconvert (Src, "srgb_rec709_scene", "acescg",
True)

.. code-tab:: bash oiiotool

Expand Down Expand Up @@ -2950,14 +2952,15 @@ Color space conversion
.. code-tab:: c++

ImageBuf Src ("tahoe.exr");
ImageBuf Dst = ImageBufAlgo::ociodisplay (Src, "sRGB", "Film", "lnf",
"", true, "SHOT", "pe0012");
ImageBuf Dst = ImageBufAlgo::ociodisplay (Src, "srgb_rec709_scene",
"Film", "lnf", "", true,
"SHOT", "pe0012");

.. code-tab:: py

Src = ImageBuf("tahoe.jpg")
Dst = ImageBufAlgo.ociodisplay (Src, "sRGB", "Film", "lnf",
"", True, "SHOT", "pe0012")
Dst = ImageBufAlgo.ociodisplay (Src, "srgb_rec709_scene", "Film",
"lnf", "", True, "SHOT", "pe0012")

.. code-tab:: bash oiiotool

Expand Down
5 changes: 3 additions & 2 deletions src/doc/pythonbindings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3610,7 +3610,8 @@ Color manipulation
.. code-block:: python

Src = ImageBuf ("tahoe.jpg")
Dst = ImageBufAlgo.colorconvert (Src, "sRGB", "scene_linear")
Dst = ImageBufAlgo.colorconvert (Src, "srgb_rec709_scene",
"scene_linear")



Expand Down Expand Up @@ -3660,7 +3661,7 @@ Color manipulation
.. code-block:: python

Src = ImageBuf ("tahoe.exr")
Dst = ImageBufAlgo.ociodisplay (Src, "sRGB", "Film", "lnf",
Dst = ImageBufAlgo.ociodisplay (Src, "srgb_rec709_scene", "Film", "lnf",
context_key="SHOT", context_value="pe0012")


Expand Down
9 changes: 6 additions & 3 deletions src/doc/stdmetadata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,12 @@ Color information
- `"lin_ap1_scene"`, `"ACEScg"` : ACEScg color space encoding.
- `"lin_ap0_scene"` : ACES2065-1, the recommended ACES space for
interchange and archiving.
- `"srgb_rec709_scene"` : Using standard (piecewise) sRGB response and
primaries. The token `"sRGB"` is treated as a synonym.
- `"g22_rec709_scene"` : Rec709/sRGB primaries, but using a response curve
- `"srgb_rec709_display"` : Using standard (piecewise) sRGB response and
primaries. The token `"sRGB"` is treated as a synonym, but it is
recommended to use the more specific interop ID.
- `"srgb_rec709_scene"` : Same response and primaries as
`"srgb_rec709_display"` but for scene referred images.
- `"g22_rec709_display"` : Rec709/sRGB primaries, but using a response curve
corresponding to gamma 2.2.

Additionally, `"scene_linear"` is a role that is appropriate for color
Expand Down
4 changes: 3 additions & 1 deletion src/dpx.imageio/dpxinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include <OpenImageIO/strutil.h>
#include <OpenImageIO/typedesc.h>

#include "imageio_pvt.h"

OIIO_PLUGIN_NAMESPACE_BEGIN


Expand Down Expand Up @@ -314,7 +316,7 @@ DPXInput::seek_subimage(int subimage, int miplevel)
switch (m_dpx.header.Transfer(subimage)) {
case dpx::kLinear: m_spec.set_colorspace("lin_rec709_scene"); break;
case dpx::kLogarithmic: m_spec.set_colorspace("KodakLog"); break;
case dpx::kITUR709: m_spec.set_colorspace("srgb_rec709_scene"); break;
case dpx::kITUR709: pvt::set_colorspace_srgb(m_spec); break;
case dpx::kUserDefined:
if (!std::isnan(m_dpx.header.Gamma()) && m_dpx.header.Gamma() != 0) {
set_colorspace_rec709_gamma(m_spec, float(m_dpx.header.Gamma()));
Expand Down
18 changes: 8 additions & 10 deletions src/dpx.imageio/dpxoutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include <OpenImageIO/strutil.h>
#include <OpenImageIO/typedesc.h>

#include "imageio_pvt.h"

OIIO_PLUGIN_NAMESPACE_BEGIN


Expand Down Expand Up @@ -436,18 +438,14 @@ DPXOutput::prep_subimage(int s, bool allocate)
m_desc = get_image_descriptor();

// transfer function
const ColorConfig& colorconfig = ColorConfig::default_colorconfig();
std::string colorspace = spec_s.get_string_attribute("oiio:ColorSpace", "");
if (colorconfig.equivalent(colorspace, "lin_rec709_scene"))
m_transfer = dpx::kLinear;
else if (colorconfig.equivalent(colorspace, "srgb_rec709_scene"))
const float gamma = pvt::get_colorspace_rec709_gamma(spec_s);
if (pvt::is_colorspace_srgb(spec_s, false))
m_transfer = dpx::kITUR709;
else if (colorconfig.equivalent(colorspace, "g22_rec709_scene")
|| colorconfig.equivalent(colorspace, "g24_rec709_scene")
|| colorconfig.equivalent(colorspace, "g18_rec709_scene")
|| Strutil::istarts_with(colorspace, "Gamma"))
else if (gamma == 1.0f)
m_transfer = dpx::kLinear;
else if (gamma != 0.0f)
m_transfer = dpx::kUserDefined;
else if (colorconfig.equivalent(colorspace, "KodakLog"))
else if (spec_s.get_string_attribute("oiio:ColorSpace") == "KodakLog")
m_transfer = dpx::kLogarithmic;
else {
std::string dpxtransfer = spec_s.get_string_attribute("dpx:Transfer",
Expand Down
7 changes: 2 additions & 5 deletions src/ffmpeg.imageio/ffmpeginput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ receive_frame(AVCodecContext* avctx, AVFrame* picture, AVPacket* avpkt)



#include "imageio_pvt.h"
#include <OpenImageIO/color.h>
#include <OpenImageIO/imageio.h>
#include <iostream>
Expand Down Expand Up @@ -549,11 +550,7 @@ FFmpegInput::open(const std::string& name, ImageSpec& spec)
= { m_codec_context->color_primaries, m_codec_context->color_trc,
m_codec_context->colorspace,
m_codec_context->color_range == AVCOL_RANGE_MPEG ? 0 : 1 };
m_spec.attribute("CICP", TypeDesc(TypeDesc::INT, 4), cicp);
const ColorConfig& colorconfig(ColorConfig::default_colorconfig());
string_view interop_id = colorconfig.get_color_interop_id(cicp);
if (!interop_id.empty())
m_spec.attribute("oiio:ColorSpace", interop_id);
pvt::set_colorspace_cicp(m_spec, cicp);

m_nsubimages = m_frames;
spec = m_spec;
Expand Down
4 changes: 3 additions & 1 deletion src/gif.imageio/gifinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <OpenImageIO/imageio.h>
#include <OpenImageIO/thread.h>

#include "imageio_pvt.h"

// GIFLIB:
// http://giflib.sourceforge.net/
// Format description:
Expand Down Expand Up @@ -259,7 +261,7 @@ GIFInput::read_subimage_metadata(ImageSpec& newspec)
newspec.nchannels = 4;
newspec.default_channel_names();
newspec.alpha_channel = 4;
newspec.set_colorspace("srgb_rec709_scene");
pvt::set_colorspace_srgb(newspec);

m_previous_disposal_method = m_disposal_method;
m_disposal_method = DISPOSAL_UNSPECIFIED;
Expand Down
11 changes: 4 additions & 7 deletions src/heif.imageio/heifinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <OpenImageIO/platform.h>
#include <OpenImageIO/tiffutils.h>

#include "imageio_pvt.h"

#include <libheif/heif_cxx.h>

#define MAKE_LIBHEIF_VERSION(a, b, c, d) \
Expand Down Expand Up @@ -273,7 +275,7 @@ HeifInput::seek_subimage(int subimage, int miplevel)
if (m_bitdepth > 8) {
m_spec.attribute("oiio:BitsPerSample", m_bitdepth);
}
m_spec.set_colorspace("srgb_rec709_scene");
pvt::set_colorspace_srgb(m_spec);

#if LIBHEIF_HAVE_VERSION(1, 9, 0)
// Read CICP. Have to use the C API to get it from the image handle,
Expand All @@ -292,12 +294,7 @@ HeifInput::seek_subimage(int subimage, int miplevel)
int(nclx->transfer_characteristics),
int(nclx->matrix_coefficients),
int(nclx->full_range_flag ? 1 : 0) };
m_spec.attribute("CICP", TypeDesc(TypeDesc::INT, 4), cicp);
const ColorConfig& colorconfig(
ColorConfig::default_colorconfig());
string_view interop_id = colorconfig.get_color_interop_id(cicp);
if (!interop_id.empty())
m_spec.attribute("oiio:ColorSpace", interop_id);
pvt::set_colorspace_cicp(m_spec, cicp);
}
heif_nclx_color_profile_free(nclx);
}
Expand Down
9 changes: 3 additions & 6 deletions src/heif.imageio/heifoutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <OpenImageIO/platform.h>
#include <OpenImageIO/tiffutils.h>

#include "imageio_pvt.h"

#include <libheif/heif_cxx.h>

#define MAKE_LIBHEIF_VERSION(a, b, c, d) \
Expand Down Expand Up @@ -250,12 +252,7 @@ HeifOutput::close()
std::unique_ptr<heif_color_profile_nclx,
void (*)(heif_color_profile_nclx*)>
nclx(heif_nclx_color_profile_alloc(), heif_nclx_color_profile_free);
const ColorConfig& colorconfig(ColorConfig::default_colorconfig());
const ParamValue* p = m_spec.find_attribute("CICP",
TypeDesc(TypeDesc::INT, 4));
string_view colorspace = m_spec.get_string_attribute("oiio:ColorSpace");
cspan<int> cicp = (p) ? p->as_cspan<int>()
: colorconfig.get_cicp(colorspace);
cspan<int> cicp = pvt::get_colorspace_cicp(m_spec);
if (!cicp.empty()) {
nclx->color_primaries = heif_color_primaries(cicp[0]);
nclx->transfer_characteristics = heif_transfer_characteristics(
Expand Down
4 changes: 3 additions & 1 deletion src/iconvert/iconvert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include <OpenImageIO/strutil.h>
#include <OpenImageIO/sysutil.h>

#include "imageio_pvt.h"


using namespace OIIO;

Expand Down Expand Up @@ -224,7 +226,7 @@ adjust_spec(ImageInput* in, ImageOutput* out, const ImageSpec& inspec,
if (gammaval != 1.0f)
outspec.attribute("oiio:Gamma", gammaval);
if (sRGB) {
outspec.set_colorspace("srgb_rec709_scene");
pvt::set_colorspace_srgb(outspec);
if (!strcmp(in->format_name(), "jpeg")
|| outspec.find_attribute("Exif:ColorSpace"))
outspec.attribute("Exif:ColorSpace", 1);
Expand Down
6 changes: 5 additions & 1 deletion src/include/OpenImageIO/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -415,10 +415,14 @@ class OIIO_API ColorConfig {
string_view get_color_interop_id(string_view colorspace) const;

/// Find color interop ID corresponding to the CICP code.
/// If prefer_image_state is set to "scene", prefer returning a scene
/// referred interop ID over a display referred interop ID if both exist.
/// Returns empty string if not found.
///
/// @version 3.1
string_view get_color_interop_id(const int cicp[4]) const;
string_view
get_color_interop_id(const int cicp[4],
string_view prefer_image_state = "display") const;

/// Return a filename or other identifier for the config we're using.
std::string configname() const;
Expand Down
20 changes: 15 additions & 5 deletions src/include/OpenImageIO/imageio.h
Original file line number Diff line number Diff line change
Expand Up @@ -912,10 +912,10 @@ class OIIO_API ImageSpec {
/// 1. Assigning to the delegate adds a metadata attribute:
///
/// ImageSpec spec;
/// spec["foo"] = 42; // int
/// spec["pi"] = float(M_PI); // float
/// spec["oiio:ColorSpace"] = "sRGB"; // string
/// spec["cameratoworld"] = Imath::Matrix44(...); // matrix
/// spec["foo"] = 42; // int
/// spec["pi"] = float(M_PI); // float
/// spec["oiio:ColorSpace"] = "srgb_rec709_display"; // string
/// spec["cameratoworld"] = Imath::Matrix44(...); // matrix
///
/// Be very careful, the attribute's type will be implied by the C++
/// type of what you assign.
Expand Down Expand Up @@ -3843,6 +3843,17 @@ OIIO_API std::string geterror(bool clear = true);
/// For more information, please see OpenImageIO's documentation on the
/// built-in PNG format support.
///
/// - `string color:prefer_image_state` ("display")
///
/// When the color space of an image file is ambiguous and can be
/// interpreted as either a display referred or scene referred, by default
/// the `oiio:ColorSpace` attribute will be set to a display color space
/// like `srgb_rec709_display`.
///
/// By setting the preferred image state to "scene", the corresponding
/// scene referred color space like `srgb_rec709_scene` will be chosen
/// instead. For textures in particular this can be a better default guess.
///
/// - `int limits:channels` (1024)
///
/// When nonzero, the maximum number of color channels in an image. Image
Expand Down Expand Up @@ -4198,7 +4209,6 @@ OIIO_API void set_colorspace(ImageSpec& spec, string_view name);
/// @version 3.0
OIIO_API void set_colorspace_rec709_gamma(ImageSpec& spec, float gamma);


/// Are the two named color spaces equivalent, based on the default color
/// config in effect?
///
Expand Down
Loading
Loading