Skip to content

Commit

Permalink
raw: expose additional white balancing hints (#4360)
Browse files Browse the repository at this point in the history
The main purpose of this change is to make it possible to use OIIO for
reading raw files in rawtoaces instead of calling LibRaw directly. There
are the changes:
- add the missing hints needed to implement all combinations of
white-balancing methods and matrix methods provided by rawtoaces.
- add the DNG-specific attributes

The change adds this functionality:
- new "raw:user_black" hint to override the default black point
- new "raw:use_auto_wb" hint to force LibRaw to white balance by
averaging over the whole image.
- new "raw:grey_box" hint to make LibRaw to white balance by averaging
over the given rectange.
- new "raw:dng:XXX" attributes added to the output ImageBuf if the input
image is a DNG file. The attributes consist of 2 sets of [calibration
illuminant; calibration matrix, XYZ to camera RGB matrix]. Note, the
current DNG standard supports up to 3 calibration illuminants, but both
LibRaw and rawtoaces only use 2 currently.

I have manually tested all permutations of white-balancing modes and
matrix methods which are currently supported by raw to aces. The images
match up to a rounding error.

The current unit tests pass, but they only seem to use the default
conversion settings. We may want to extend those. I'm not clear on how
to do that, there are multiple reference images for different versions
of LibRaw, not sure if I will have to re-generate all of them. I intend
to make more changes to the raw plugin soon, may come back to updating
tests during/after that.

There are currently no tests using DNG files, so the new DNG-specific
attributes are not covered. The code relying on those in rawtoaces works
fine.

I have also updated the documentation to add the new hints, however, I
haven't been able to build the documentation.

Signed-off-by: Anton Dukhovnikov <[email protected]>
  • Loading branch information
antond-weta authored Aug 7, 2024
1 parent fb9d818 commit 3cb2acf
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 17 deletions.
25 changes: 23 additions & 2 deletions src/doc/builtinplugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2066,14 +2066,34 @@ options are supported:
- If nonzero, will use libraw's exposure correction. (Default: 0)
* - ``raw:use_camera_wb``
- int
- If 1, use libraw's camera white balance adjustment. (Default: 1)
- If 1, use libraw's camera white balance adjustment. Takes precedence
over ``raw:use_auto_wb``, ``raw:greybox``, ``raw:user_mul``.
(Default: 1)
* - ``raw:use_auto_wb``
- int
- If 1, white balance automatically by averaging over the entire image.
Only applies if ``raw:use_camera_wb`` is not equal to 0. Takes
precedence over ``raw:greybox``, ``raw:user_mul``.
(Default: 0)
* - ``raw:greybox``
- int[4]
- White balance by averaging over the given box. The four values are the
X and Y coordinate of the top-left corner, the width and the height.
Only applies if the size is non-zero, and ``raw:use_camera_wb`` is not
equal to 0, ``raw:use_auto_wb`` is not equal to 0. Takes
precedence over ``raw:user_mul``.
(Default: 0, 0, 0, 0; meaning no correction.)
* - ``raw:use_camera_matrix``
- int
- Whether to use the embedded color profile, if it's present: 0 =
never, 1 (default) = only for DNG files, 3 = always.
* - ``raw:adjust_maximum_thr``
- float
- If nonzero, auto-adjusting maximum value. (Default:0.0)
* - ``raw:user_black``
- int
- If not negative, sets the camera minimum value that will be normalized to
appear 0. (Default: -1)
* - ``raw:user_sat``
- int
- If nonzero, sets the camera maximum value that will be normalized to
Expand All @@ -2090,7 +2110,8 @@ options are supported:
* - ``raw:user_mul``
- float[4]
- Sets user white balance coefficients. Only applies if ``raw:use_camera_wb``
is not equal to 0.
is not equal to 0, ``raw:use_auto_wb`` is not equal to 0, and the
``raw:greybox`` box is zero size.
* - ``raw:ColorSpace``
- string
- Which color primaries to use for the returned pixel values: ``raw``,
Expand Down
74 changes: 59 additions & 15 deletions src/raw.imageio/rawinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,9 @@ RawInput::open_raw(bool unpack, const std::string& name,
// Turn off maximum threshold value (unless set to non-zero)
m_processor->imgdata.params.adjust_maximum_thr
= config.get_float_attribute("raw:adjust_maximum_thr", 0.0f);
// Set camera minimum value if "raw:user_black" is not negative
m_processor->imgdata.params.user_black
= config.get_int_attribute("raw:user_black", -1);
// Set camera maximum value if "raw:user_sat" is not 0
m_processor->imgdata.params.user_sat
= config.get_int_attribute("raw:user_sat", 0);
Expand Down Expand Up @@ -502,21 +505,34 @@ RawInput::open_raw(bool unpack, const std::string& name,
params.user_mul[2] = norm[2];
params.user_mul[3] = norm[3];
} else {
// Set user white balance coefficients.
// Only has effect if "raw:use_camera_wb" is equal to 0,
// i.e. we are not using the camera white balance
auto p = config.find_attribute("raw:user_mul");
if (p && p->type() == TypeDesc(TypeDesc::FLOAT, 4)) {
m_processor->imgdata.params.user_mul[0] = p->get<float>(0);
m_processor->imgdata.params.user_mul[1] = p->get<float>(1);
m_processor->imgdata.params.user_mul[2] = p->get<float>(2);
m_processor->imgdata.params.user_mul[3] = p->get<float>(3);
}
if (p && p->type() == TypeDesc(TypeDesc::DOUBLE, 4)) {
m_processor->imgdata.params.user_mul[0] = p->get<double>(0);
m_processor->imgdata.params.user_mul[1] = p->get<double>(1);
m_processor->imgdata.params.user_mul[2] = p->get<double>(2);
m_processor->imgdata.params.user_mul[3] = p->get<double>(3);
if (config.get_int_attribute("raw:use_auto_wb", 0) == 1) {
m_processor->imgdata.params.use_auto_wb = 1;
} else {
auto p = config.find_attribute("raw:greybox");
if (p && p->type() == TypeDesc(TypeDesc::INT, 4)) {
// p->get<int>() didn't work for me here
m_processor->imgdata.params.greybox[0] = p->get_int_indexed(0);
m_processor->imgdata.params.greybox[1] = p->get_int_indexed(1);
m_processor->imgdata.params.greybox[2] = p->get_int_indexed(2);
m_processor->imgdata.params.greybox[3] = p->get_int_indexed(3);
} else {
// Set user white balance coefficients.
// Only has effect if "raw:use_camera_wb" is equal to 0,
// i.e. we are not using the camera white balance
auto p = config.find_attribute("raw:user_mul");
if (p && p->type() == TypeDesc(TypeDesc::FLOAT, 4)) {
m_processor->imgdata.params.user_mul[0] = p->get<float>(0);
m_processor->imgdata.params.user_mul[1] = p->get<float>(1);
m_processor->imgdata.params.user_mul[2] = p->get<float>(2);
m_processor->imgdata.params.user_mul[3] = p->get<float>(3);
}
if (p && p->type() == TypeDesc(TypeDesc::DOUBLE, 4)) {
m_processor->imgdata.params.user_mul[0] = p->get<double>(0);
m_processor->imgdata.params.user_mul[1] = p->get<double>(1);
m_processor->imgdata.params.user_mul[2] = p->get<double>(2);
m_processor->imgdata.params.user_mul[3] = p->get<double>(3);
}
}
}
}

Expand Down Expand Up @@ -1319,6 +1335,34 @@ RawInput::get_colorinfo()
cspan<float>(&(m_processor->imgdata.color.cam_xyz[0][0]),
&(m_processor->imgdata.color.cam_xyz[3][3])),
false, 0.f);

if (m_processor->imgdata.idata.dng_version) {
add("raw", "dng:version", m_processor->imgdata.idata.dng_version);

auto const& c = m_processor->imgdata.rawdata.color;

#if LIBRAW_VERSION >= LIBRAW_MAKE_VERSION(0, 20, 0)
add("raw", "dng:baseline_exposure", c.dng_levels.baseline_exposure);
#else
add("raw", "dng:baseline_exposure", c.baseline_exposure);
#endif

for (int i = 0; i < 2; i++) {
std::string index = std::to_string(i + 1);
add("raw", "dng:calibration_illuminant" + index,
c.dng_color[i].illuminant);

add("raw", "dng:color_matrix" + index,
cspan<float>(&(c.dng_color[i].colormatrix[0][0]),
&(c.dng_color[i].colormatrix[3][3])),
false, 0.f);

add("raw", "dng:camera_calibration" + index,
cspan<float>(&(c.dng_color[i].calibration[0][0]),
&(c.dng_color[i].calibration[3][4])),
false, 0.f);
}
}
}


Expand Down

0 comments on commit 3cb2acf

Please sign in to comment.