Skip to content

Commit 3cb2acf

Browse files
authored
raw: expose additional white balancing hints (#4360)
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 <antond@wetafx.co.nz>
1 parent fb9d818 commit 3cb2acf

2 files changed

Lines changed: 82 additions & 17 deletions

File tree

src/doc/builtinplugins.rst

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,14 +2066,34 @@ options are supported:
20662066
- If nonzero, will use libraw's exposure correction. (Default: 0)
20672067
* - ``raw:use_camera_wb``
20682068
- int
2069-
- If 1, use libraw's camera white balance adjustment. (Default: 1)
2069+
- If 1, use libraw's camera white balance adjustment. Takes precedence
2070+
over ``raw:use_auto_wb``, ``raw:greybox``, ``raw:user_mul``.
2071+
(Default: 1)
2072+
* - ``raw:use_auto_wb``
2073+
- int
2074+
- If 1, white balance automatically by averaging over the entire image.
2075+
Only applies if ``raw:use_camera_wb`` is not equal to 0. Takes
2076+
precedence over ``raw:greybox``, ``raw:user_mul``.
2077+
(Default: 0)
2078+
* - ``raw:greybox``
2079+
- int[4]
2080+
- White balance by averaging over the given box. The four values are the
2081+
X and Y coordinate of the top-left corner, the width and the height.
2082+
Only applies if the size is non-zero, and ``raw:use_camera_wb`` is not
2083+
equal to 0, ``raw:use_auto_wb`` is not equal to 0. Takes
2084+
precedence over ``raw:user_mul``.
2085+
(Default: 0, 0, 0, 0; meaning no correction.)
20702086
* - ``raw:use_camera_matrix``
20712087
- int
20722088
- Whether to use the embedded color profile, if it's present: 0 =
20732089
never, 1 (default) = only for DNG files, 3 = always.
20742090
* - ``raw:adjust_maximum_thr``
20752091
- float
20762092
- If nonzero, auto-adjusting maximum value. (Default:0.0)
2093+
* - ``raw:user_black``
2094+
- int
2095+
- If not negative, sets the camera minimum value that will be normalized to
2096+
appear 0. (Default: -1)
20772097
* - ``raw:user_sat``
20782098
- int
20792099
- If nonzero, sets the camera maximum value that will be normalized to
@@ -2090,7 +2110,8 @@ options are supported:
20902110
* - ``raw:user_mul``
20912111
- float[4]
20922112
- Sets user white balance coefficients. Only applies if ``raw:use_camera_wb``
2093-
is not equal to 0.
2113+
is not equal to 0, ``raw:use_auto_wb`` is not equal to 0, and the
2114+
``raw:greybox`` box is zero size.
20942115
* - ``raw:ColorSpace``
20952116
- string
20962117
- Which color primaries to use for the returned pixel values: ``raw``,

src/raw.imageio/rawinput.cpp

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,9 @@ RawInput::open_raw(bool unpack, const std::string& name,
459459
// Turn off maximum threshold value (unless set to non-zero)
460460
m_processor->imgdata.params.adjust_maximum_thr
461461
= config.get_float_attribute("raw:adjust_maximum_thr", 0.0f);
462+
// Set camera minimum value if "raw:user_black" is not negative
463+
m_processor->imgdata.params.user_black
464+
= config.get_int_attribute("raw:user_black", -1);
462465
// Set camera maximum value if "raw:user_sat" is not 0
463466
m_processor->imgdata.params.user_sat
464467
= config.get_int_attribute("raw:user_sat", 0);
@@ -502,21 +505,34 @@ RawInput::open_raw(bool unpack, const std::string& name,
502505
params.user_mul[2] = norm[2];
503506
params.user_mul[3] = norm[3];
504507
} else {
505-
// Set user white balance coefficients.
506-
// Only has effect if "raw:use_camera_wb" is equal to 0,
507-
// i.e. we are not using the camera white balance
508-
auto p = config.find_attribute("raw:user_mul");
509-
if (p && p->type() == TypeDesc(TypeDesc::FLOAT, 4)) {
510-
m_processor->imgdata.params.user_mul[0] = p->get<float>(0);
511-
m_processor->imgdata.params.user_mul[1] = p->get<float>(1);
512-
m_processor->imgdata.params.user_mul[2] = p->get<float>(2);
513-
m_processor->imgdata.params.user_mul[3] = p->get<float>(3);
514-
}
515-
if (p && p->type() == TypeDesc(TypeDesc::DOUBLE, 4)) {
516-
m_processor->imgdata.params.user_mul[0] = p->get<double>(0);
517-
m_processor->imgdata.params.user_mul[1] = p->get<double>(1);
518-
m_processor->imgdata.params.user_mul[2] = p->get<double>(2);
519-
m_processor->imgdata.params.user_mul[3] = p->get<double>(3);
508+
if (config.get_int_attribute("raw:use_auto_wb", 0) == 1) {
509+
m_processor->imgdata.params.use_auto_wb = 1;
510+
} else {
511+
auto p = config.find_attribute("raw:greybox");
512+
if (p && p->type() == TypeDesc(TypeDesc::INT, 4)) {
513+
// p->get<int>() didn't work for me here
514+
m_processor->imgdata.params.greybox[0] = p->get_int_indexed(0);
515+
m_processor->imgdata.params.greybox[1] = p->get_int_indexed(1);
516+
m_processor->imgdata.params.greybox[2] = p->get_int_indexed(2);
517+
m_processor->imgdata.params.greybox[3] = p->get_int_indexed(3);
518+
} else {
519+
// Set user white balance coefficients.
520+
// Only has effect if "raw:use_camera_wb" is equal to 0,
521+
// i.e. we are not using the camera white balance
522+
auto p = config.find_attribute("raw:user_mul");
523+
if (p && p->type() == TypeDesc(TypeDesc::FLOAT, 4)) {
524+
m_processor->imgdata.params.user_mul[0] = p->get<float>(0);
525+
m_processor->imgdata.params.user_mul[1] = p->get<float>(1);
526+
m_processor->imgdata.params.user_mul[2] = p->get<float>(2);
527+
m_processor->imgdata.params.user_mul[3] = p->get<float>(3);
528+
}
529+
if (p && p->type() == TypeDesc(TypeDesc::DOUBLE, 4)) {
530+
m_processor->imgdata.params.user_mul[0] = p->get<double>(0);
531+
m_processor->imgdata.params.user_mul[1] = p->get<double>(1);
532+
m_processor->imgdata.params.user_mul[2] = p->get<double>(2);
533+
m_processor->imgdata.params.user_mul[3] = p->get<double>(3);
534+
}
535+
}
520536
}
521537
}
522538

@@ -1319,6 +1335,34 @@ RawInput::get_colorinfo()
13191335
cspan<float>(&(m_processor->imgdata.color.cam_xyz[0][0]),
13201336
&(m_processor->imgdata.color.cam_xyz[3][3])),
13211337
false, 0.f);
1338+
1339+
if (m_processor->imgdata.idata.dng_version) {
1340+
add("raw", "dng:version", m_processor->imgdata.idata.dng_version);
1341+
1342+
auto const& c = m_processor->imgdata.rawdata.color;
1343+
1344+
#if LIBRAW_VERSION >= LIBRAW_MAKE_VERSION(0, 20, 0)
1345+
add("raw", "dng:baseline_exposure", c.dng_levels.baseline_exposure);
1346+
#else
1347+
add("raw", "dng:baseline_exposure", c.baseline_exposure);
1348+
#endif
1349+
1350+
for (int i = 0; i < 2; i++) {
1351+
std::string index = std::to_string(i + 1);
1352+
add("raw", "dng:calibration_illuminant" + index,
1353+
c.dng_color[i].illuminant);
1354+
1355+
add("raw", "dng:color_matrix" + index,
1356+
cspan<float>(&(c.dng_color[i].colormatrix[0][0]),
1357+
&(c.dng_color[i].colormatrix[3][3])),
1358+
false, 0.f);
1359+
1360+
add("raw", "dng:camera_calibration" + index,
1361+
cspan<float>(&(c.dng_color[i].calibration[0][0]),
1362+
&(c.dng_color[i].calibration[3][4])),
1363+
false, 0.f);
1364+
}
1365+
}
13221366
}
13231367

13241368

0 commit comments

Comments
 (0)