Skip to content

Commit 07ee76e

Browse files
committed
feat: Refactor writing color space metadata to unify behavior
This adds new functions to get and set colorspaces in a ImageSpace, to make logic between file formats more consistent. * pvt::set_colorspace_srgb and pvt::is_colorspace_srgb * pvt::get_colorspace_rec709_gamma * pvt::get_colorspace_icc_profile * pvt::set_colorspace_cicp and pvt::get_colorspace_cicp This fixes an issue where tga and rla were incorrectly using g22_rec709 and g18_rec709 without _scene suffix, and not handling g24_rec709. There is existing consistency in that some file formats assume an empty oiio:ColorSpace to mean sRGB, and some don't. This inconsistency is preserved. Signed-off-by: Brecht Van Lommel <[email protected]>
1 parent 9229cf3 commit 07ee76e

File tree

30 files changed

+306
-274
lines changed

30 files changed

+306
-274
lines changed

src/bmp.imageio/bmpinput.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <OpenImageIO/fmath.h>
99
#include <OpenImageIO/imageio.h>
1010

11+
#include "imageio_pvt.h"
12+
1113
#include "bmp_pvt.h"
1214

1315
OIIO_PLUGIN_NAMESPACE_BEGIN
@@ -262,7 +264,8 @@ BmpInput::open(const std::string& name, ImageSpec& newspec,
262264
// Default presumption is that a BMP file is meant to look reasonable on a
263265
// display, so assume it's sRGB. This is not really correct -- see the
264266
// comments below.
265-
m_spec.attribute("oiio:ColorSpace", "srgb_rec709_scene");
267+
const bool erase_other_attributes = false;
268+
pvt::set_colorspace_srgb(m_spec, erase_other_attributes);
266269
#if 0
267270
if (m_dib_header.size >= WINDOWS_V4
268271
&& m_dib_header.cs_type == CSType::CalibratedRGB) {

src/dds.imageio/ddsinput.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include <OpenImageIO/parallel.h>
1616
#include <OpenImageIO/typedesc.h>
1717

18+
#include "imageio_pvt.h"
19+
1820
#include "dds_pvt.h"
1921
#define BCDEC_IMPLEMENTATION
2022
#include "bcdec.h"
@@ -828,7 +830,7 @@ DDSInput::seek_subimage(int subimage, int miplevel)
828830
if (bpp != 0)
829831
m_spec.attribute("oiio:BitsPerSample", bpp);
830832

831-
const char* colorspace = nullptr;
833+
bool is_srgb = false;
832834

833835
if (m_dds.fmt.fourCC == DDS_4CC_DX10) {
834836
switch (m_dx10.dxgiFormat) {
@@ -838,18 +840,17 @@ DDSInput::seek_subimage(int subimage, int miplevel)
838840
case DDS_FORMAT_BC7_UNORM_SRGB:
839841
case DDS_FORMAT_R8G8B8A8_UNORM_SRGB:
840842
case DDS_FORMAT_B8G8R8A8_UNORM_SRGB:
841-
case DDS_FORMAT_B8G8R8X8_UNORM_SRGB:
842-
colorspace = "srgb_rec709_scene";
843-
break;
843+
case DDS_FORMAT_B8G8R8X8_UNORM_SRGB: is_srgb = true; break;
844844
}
845845
}
846846

847-
// linear color space for HDR-ish images
848-
if (colorspace == nullptr
849-
&& (basetype == TypeDesc::HALF || basetype == TypeDesc::FLOAT))
850-
colorspace = "lin_rec709_scene";
851-
852-
m_spec.set_colorspace(colorspace);
847+
if (is_srgb) {
848+
pvt::set_colorspace_srgb(m_spec);
849+
} else if (!is_srgb
850+
&& (basetype == TypeDesc::HALF || basetype == TypeDesc::FLOAT)) {
851+
// linear color space for HDR-ish images
852+
m_spec.set_colorspace("lin_rec709_scene");
853+
}
853854

854855
m_spec.default_channel_names();
855856
// Special case: if a 2-channel DDS RG or YA?

src/dpx.imageio/dpxinput.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include <OpenImageIO/strutil.h>
3030
#include <OpenImageIO/typedesc.h>
3131

32+
#include "imageio_pvt.h"
33+
3234
OIIO_PLUGIN_NAMESPACE_BEGIN
3335

3436

@@ -314,7 +316,7 @@ DPXInput::seek_subimage(int subimage, int miplevel)
314316
switch (m_dpx.header.Transfer(subimage)) {
315317
case dpx::kLinear: m_spec.set_colorspace("lin_rec709_scene"); break;
316318
case dpx::kLogarithmic: m_spec.set_colorspace("KodakLog"); break;
317-
case dpx::kITUR709: m_spec.set_colorspace("srgb_rec709_scene"); break;
319+
case dpx::kITUR709: pvt::set_colorspace_srgb(m_spec); break;
318320
case dpx::kUserDefined:
319321
if (!std::isnan(m_dpx.header.Gamma()) && m_dpx.header.Gamma() != 0) {
320322
set_colorspace_rec709_gamma(m_spec, float(m_dpx.header.Gamma()));

src/dpx.imageio/dpxoutput.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <OpenImageIO/strutil.h>
1919
#include <OpenImageIO/typedesc.h>
2020

21+
#include "imageio_pvt.h"
22+
2123
OIIO_PLUGIN_NAMESPACE_BEGIN
2224

2325

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

438440
// transfer function
439-
const ColorConfig& colorconfig = ColorConfig::default_colorconfig();
440-
std::string colorspace = spec_s.get_string_attribute("oiio:ColorSpace", "");
441-
if (colorconfig.equivalent(colorspace, "lin_rec709_scene"))
442-
m_transfer = dpx::kLinear;
443-
else if (colorconfig.equivalent(colorspace, "srgb_rec709_scene"))
441+
const float gamma = pvt::get_colorspace_rec709_gamma(spec_s);
442+
if (pvt::is_colorspace_srgb(spec_s, false))
444443
m_transfer = dpx::kITUR709;
445-
else if (colorconfig.equivalent(colorspace, "g22_rec709_scene")
446-
|| colorconfig.equivalent(colorspace, "g24_rec709_scene")
447-
|| colorconfig.equivalent(colorspace, "g18_rec709_scene")
448-
|| Strutil::istarts_with(colorspace, "Gamma"))
444+
else if (gamma == 1.0f)
445+
m_transfer = dpx::kLinear;
446+
else if (gamma != 0.0f)
449447
m_transfer = dpx::kUserDefined;
450-
else if (colorconfig.equivalent(colorspace, "KodakLog"))
448+
else if (spec_s.get_string_attribute("oiio:ColorSpace") == "KodakLog")
451449
m_transfer = dpx::kLogarithmic;
452450
else {
453451
std::string dpxtransfer = spec_s.get_string_attribute("dpx:Transfer",

src/ffmpeg.imageio/ffmpeginput.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ receive_frame(AVCodecContext* avctx, AVFrame* picture, AVPacket* avpkt)
7171

7272

7373

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

558555
m_nsubimages = m_frames;
559556
spec = m_spec;

src/gif.imageio/gifinput.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include <OpenImageIO/imageio.h>
1313
#include <OpenImageIO/thread.h>
1414

15+
#include "imageio_pvt.h"
16+
1517
// GIFLIB:
1618
// http://giflib.sourceforge.net/
1719
// Format description:
@@ -259,7 +261,7 @@ GIFInput::read_subimage_metadata(ImageSpec& newspec)
259261
newspec.nchannels = 4;
260262
newspec.default_channel_names();
261263
newspec.alpha_channel = 4;
262-
newspec.set_colorspace("srgb_rec709_scene");
264+
pvt::set_colorspace_srgb(newspec);
263265

264266
m_previous_disposal_method = m_disposal_method;
265267
m_disposal_method = DISPOSAL_UNSPECIFIED;

src/heif.imageio/heifinput.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <OpenImageIO/platform.h>
1010
#include <OpenImageIO/tiffutils.h>
1111

12+
#include "imageio_pvt.h"
13+
1214
#include <libheif/heif_cxx.h>
1315

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

278280
#if LIBHEIF_HAVE_VERSION(1, 9, 0)
279281
// Read CICP. Have to use the C API to get it from the image handle,
@@ -292,12 +294,7 @@ HeifInput::seek_subimage(int subimage, int miplevel)
292294
int(nclx->transfer_characteristics),
293295
int(nclx->matrix_coefficients),
294296
int(nclx->full_range_flag ? 1 : 0) };
295-
m_spec.attribute("CICP", TypeDesc(TypeDesc::INT, 4), cicp);
296-
const ColorConfig& colorconfig(
297-
ColorConfig::default_colorconfig());
298-
string_view interop_id = colorconfig.get_color_interop_id(cicp);
299-
if (!interop_id.empty())
300-
m_spec.attribute("oiio:ColorSpace", interop_id);
297+
pvt::set_colorspace_cicp(m_spec, cicp);
301298
}
302299
heif_nclx_color_profile_free(nclx);
303300
}

src/heif.imageio/heifoutput.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <OpenImageIO/platform.h>
1111
#include <OpenImageIO/tiffutils.h>
1212

13+
#include "imageio_pvt.h"
14+
1315
#include <libheif/heif_cxx.h>
1416

1517
#define MAKE_LIBHEIF_VERSION(a, b, c, d) \
@@ -250,12 +252,7 @@ HeifOutput::close()
250252
std::unique_ptr<heif_color_profile_nclx,
251253
void (*)(heif_color_profile_nclx*)>
252254
nclx(heif_nclx_color_profile_alloc(), heif_nclx_color_profile_free);
253-
const ColorConfig& colorconfig(ColorConfig::default_colorconfig());
254-
const ParamValue* p = m_spec.find_attribute("CICP",
255-
TypeDesc(TypeDesc::INT, 4));
256-
string_view colorspace = m_spec.get_string_attribute("oiio:ColorSpace");
257-
cspan<int> cicp = (p) ? p->as_cspan<int>()
258-
: colorconfig.get_cicp(colorspace);
255+
cspan<int> cicp = pvt::get_colorspace_cicp(m_spec);
259256
if (!cicp.empty()) {
260257
nclx->color_primaries = heif_color_primaries(cicp[0]);
261258
nclx->transfer_characteristics = heif_transfer_characteristics(

src/iconvert/iconvert.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <OpenImageIO/strutil.h>
1919
#include <OpenImageIO/sysutil.h>
2020

21+
#include "imageio_pvt.h"
22+
2123

2224
using namespace OIIO;
2325

@@ -224,7 +226,7 @@ adjust_spec(ImageInput* in, ImageOutput* out, const ImageSpec& inspec,
224226
if (gammaval != 1.0f)
225227
outspec.attribute("oiio:Gamma", gammaval);
226228
if (sRGB) {
227-
outspec.set_colorspace("srgb_rec709_scene");
229+
pvt::set_colorspace_srgb(outspec);
228230
if (!strcmp(in->format_name(), "jpeg")
229231
|| outspec.find_attribute("Exif:ColorSpace"))
230232
outspec.attribute("Exif:ColorSpace", 1);

src/include/OpenImageIO/imageio.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4198,7 +4198,6 @@ OIIO_API void set_colorspace(ImageSpec& spec, string_view name);
41984198
/// @version 3.0
41994199
OIIO_API void set_colorspace_rec709_gamma(ImageSpec& spec, float gamma);
42004200

4201-
42024201
/// Are the two named color spaces equivalent, based on the default color
42034202
/// config in effect?
42044203
///

0 commit comments

Comments
 (0)