Call the reference curve what it is, and drop wording that reads as copying
The view transform's second curve is the DNG SDK's published reference
rendering — the ACR3 default curve applied by RefBaselineRGBTone — so
it is the "DNG Reference" curve in the panel, D21 and the code, not a
name borrowed from another product. Comments and docs that justified a
choice by another editor doing it ("as their Amount", "so a
photographer arriving from it finds the name") now give the actual
reason. The Vivid presets no longer describe themselves as reaching
for another editor's look; they are DarkRoom's own.
Factual mentions stay: which program wrote the library's DNGs, what
was measured against, and preset import. camera-profiles.md gains §15,
on starting a photograph from the edit it already carries.
This commit is contained in:
@@ -228,7 +228,7 @@ fn camera_raw_tone_agrees_with_its_cpu_reference() {
|
|||||||
dr_pipeline::view::DEFAULT_WHITE,
|
dr_pipeline::view::DEFAULT_WHITE,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
"Camera Raw tone",
|
"DNG reference tone",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ fn sigmoid_chain() -> EditGraph {
|
|||||||
#[test]
|
#[test]
|
||||||
fn camera_raw_tone_agrees_with_the_acr3_curve() {
|
fn camera_raw_tone_agrees_with_the_acr3_curve() {
|
||||||
// TRACES: FR-DEV-3j
|
// TRACES: FR-DEV-3j
|
||||||
// D21: a raw with no profile, Camera Raw's curve chosen, renders a grey
|
// D21: a raw with no profile, the DNG reference curve chosen, renders a grey
|
||||||
// through the ACR3 default curve, which the profile buffer's placeholder
|
// through the ACR3 default curve, which the profile buffer's placeholder
|
||||||
// carries.
|
// carries.
|
||||||
let Some(ctx) = ctx() else {
|
let Some(ctx) = ctx() else {
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
drpl 1
|
drpl 1
|
||||||
|
|
||||||
# Vivid: more colour than the default rendering, for the photographer used
|
# Vivid: more colour than the default rendering (camera-profiles.md §9).
|
||||||
# to Lightroom's richer starting point (camera-profiles.md §9).
|
|
||||||
#
|
#
|
||||||
# That difference is mostly Camera Raw's tone curve, not the camera
|
# These do the work themselves, and work on every photograph — a JPEG, a body with no profile. They lean on
|
||||||
# profile: Adobe Standard's look table, which D20 applies, desaturates dark
|
|
||||||
# tones (camera-profiles.md §1). So these do the work themselves, and work
|
|
||||||
# on every photograph — a JPEG, a body with no profile. They lean on
|
|
||||||
# vibrance before saturation: vibrance lifts muted colours most and holds
|
# vibrance before saturation: vibrance lifts muted colours most and holds
|
||||||
# skin back, so a frame gets richer before anything in it looks painted.
|
# skin back, so a frame gets richer before anything in it looks painted.
|
||||||
# Saturation, which moves every colour alike, is used sparingly on top.
|
# Saturation, which moves every colour alike, is used sparingly on top.
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
//! TRACES: FR-DEV-3j | FR-DEV-3e
|
//! TRACES: FR-DEV-3j | FR-DEV-3e
|
||||||
//! Camera Raw's tone, as a rendering the view transform can choose (D21).
|
//! The DNG SDK's reference tone, as a rendering the view transform can
|
||||||
|
//! choose (D21).
|
||||||
//!
|
//!
|
||||||
//! Lightroom's colour is mostly its tone curve (camera-profiles.md §1): the
|
//! The DNG specification's reference rendering runs a raw through the
|
||||||
//! profile's `ProfileToneCurve`, or the ACR3 default for a profile with none.
|
//! profile's `ProfileToneCurve`, or the ACR3 default for a profile with none.
|
||||||
//! Half of what the curve does is *how* it is applied. Camera Raw's
|
//! Half of what the curve does is *how* it is applied. The SDK's
|
||||||
//! `RefBaselineRGBTone` runs it on the largest and the smallest channel, and
|
//! `RefBaselineRGBTone` runs it on the largest and the smallest channel, and
|
||||||
//! places the middle channel at the fraction between them it had before. Hue
|
//! places the middle channel at the fraction between them it had before. Hue
|
||||||
//! is kept; saturation rises wherever the curve is steeper than the
|
//! is kept; saturation rises wherever the curve is steeper than the
|
||||||
//! diagonal, which for the ACR3 curve is the shadows and the midtones —
|
//! diagonal, which for the ACR3 curve is the shadows and the midtones.
|
||||||
//! where Adobe Standard's look table desaturated to compensate.
|
|
||||||
//!
|
//!
|
||||||
//! It runs in linear ProPhoto, as Camera Raw does, on values clipped to
|
//! It runs in linear ProPhoto, as the SDK does, on values clipped to
|
||||||
//! `[0, 1]`; its output is linear and goes to the output transform as the
|
//! `[0, 1]`; its output is linear and goes to the output transform as the
|
||||||
//! sigmoid's does. The curve is read from the profile buffer
|
//! sigmoid's does. The curve is read from the profile buffer
|
||||||
//! (`ops::camera_profile::profile_buffer`), which always carries one.
|
//! (`ops::camera_profile::profile_buffer`), which always carries one.
|
||||||
@@ -22,14 +22,14 @@ use crate::ops::camera_profile::{mul, working_prophoto};
|
|||||||
use crate::view::{DEFAULT_CONTRAST, DEFAULT_WHITE, SCENE_GREY};
|
use crate::view::{DEFAULT_CONTRAST, DEFAULT_WHITE, SCENE_GREY};
|
||||||
|
|
||||||
/// The input scale for a white point: 1 at the default, so sensor white is
|
/// The input scale for a white point: 1 at the default, so sensor white is
|
||||||
/// display white as in Camera Raw; each stop of `white` above it halves the
|
/// display white as in the SDK's reference; each stop of `white` above it halves the
|
||||||
/// input.
|
/// input.
|
||||||
pub fn input_scale(white: f32) -> f32 {
|
pub fn input_scale(white: f32) -> f32 {
|
||||||
(DEFAULT_WHITE - white).exp2()
|
(DEFAULT_WHITE - white).exp2()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The power the input is bent by about middle grey: 1 at the default
|
/// The power the input is bent by about middle grey: 1 at the default
|
||||||
/// contrast, so the curve is Camera Raw's untouched.
|
/// contrast, so the curve is the reference's untouched.
|
||||||
pub fn contrast_power(contrast: f32) -> f32 {
|
pub fn contrast_power(contrast: f32) -> f32 {
|
||||||
contrast / DEFAULT_CONTRAST
|
contrast / DEFAULT_CONTRAST
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ fn rgb_tone(curve: &[f32], p: [f32; 3]) -> [f32; 3] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// TRACES: FR-DEV-3j
|
/// TRACES: FR-DEV-3j
|
||||||
/// The view transform's Camera Raw rendering of one working-space colour.
|
/// The view transform's DNG reference rendering of one working-space colour.
|
||||||
pub fn apply_reference(curve: &[f32], c: [f32; 3], contrast: f32, white: f32) -> [f32; 3] {
|
pub fn apply_reference(curve: &[f32], c: [f32; 3], contrast: f32, white: f32) -> [f32; 3] {
|
||||||
let (to, back) = working_prophoto();
|
let (to, back) = working_prophoto();
|
||||||
let scale = input_scale(white);
|
let scale = input_scale(white);
|
||||||
@@ -73,7 +73,7 @@ fn camera_raw_curve(x: f32) -> f32 {
|
|||||||
return mix(profile_table[base + i].x, profile_table[base + i + 1u].x, s - f32(i));
|
return mix(profile_table[base + i].x, profile_table[base + i + 1u].x, s - f32(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Camera Raw's RGBTone: the curve on the largest and smallest channel, the
|
// The SDK's RGBTone: the curve on the largest and smallest channel, the
|
||||||
// middle one kept at its fraction between them, so hue survives.
|
// middle one kept at its fraction between them, so hue survives.
|
||||||
fn camera_raw_tone(c: vec3<f32>, scale: f32, power: f32, grey: f32) -> vec3<f32> {
|
fn camera_raw_tone(c: vec3<f32>, scale: f32, power: f32, grey: f32) -> vec3<f32> {
|
||||||
var p = PROFILE_FROM_WORKING * c * scale;
|
var p = PROFILE_FROM_WORKING * c * scale;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ pub const LOOK: ParamId = ParamId("look");
|
|||||||
/// The look's strength at which the LookTable is applied as the profile
|
/// The look's strength at which the LookTable is applied as the profile
|
||||||
/// states it, in percent.
|
/// states it, in percent.
|
||||||
pub const DEFAULT_LOOK: f32 = 100.0;
|
pub const DEFAULT_LOOK: f32 = 100.0;
|
||||||
/// Twice the profile's look: Lightroom's *Amount* reaches the same.
|
/// Twice the profile's look.
|
||||||
pub const MAX_LOOK: f32 = 200.0;
|
pub const MAX_LOOK: f32 = 200.0;
|
||||||
|
|
||||||
/// Entries of the buffer's header, before the entries themselves: one
|
/// Entries of the buffer's header, before the entries themselves: one
|
||||||
@@ -130,7 +130,7 @@ fn wgsl_mat(m: &[f32; 9]) -> String {
|
|||||||
|
|
||||||
/// The working space to ProPhoto and back, as WGSL constants, and where
|
/// The working space to ProPhoto and back, as WGSL constants, and where
|
||||||
/// the profile buffer's sections begin. A helper of its own because the
|
/// the profile buffer's sections begin. A helper of its own because the
|
||||||
/// view transform's Camera Raw curve needs it too, and helpers are emitted
|
/// view transform's DNG reference curve needs it too, and helpers are emitted
|
||||||
/// once each, in the order first asked for.
|
/// once each, in the order first asked for.
|
||||||
pub(crate) static PROPHOTO_HELPER: LazyLock<Helper> = LazyLock::new(|| {
|
pub(crate) static PROPHOTO_HELPER: LazyLock<Helper> = LazyLock::new(|| {
|
||||||
let (to, back) = working_prophoto();
|
let (to, back) = working_prophoto();
|
||||||
@@ -390,7 +390,7 @@ if (hue_sat_dims.x > 0.0 || look_dims.x > 0.0) {
|
|||||||
/// The curve is always there: the profile's own where it has one, Camera
|
/// The curve is always there: the profile's own where it has one, Camera
|
||||||
/// Raw's ACR3 default otherwise — including in the placeholder every source
|
/// Raw's ACR3 default otherwise — including in the placeholder every source
|
||||||
/// without a profile binds, whose tables are absent, so a raw with no
|
/// without a profile binds, whose tables are absent, so a raw with no
|
||||||
/// profile still renders through Camera Raw's tone (D21).
|
/// profile still has the reference tone curve when it is chosen (D21).
|
||||||
pub fn profile_buffer(tables: Option<&ProfileTables>) -> Vec<[f32; 4]> {
|
pub fn profile_buffer(tables: Option<&ProfileTables>) -> Vec<[f32; 4]> {
|
||||||
let header = |t: Option<&HueSatTable>| match t {
|
let header = |t: Option<&HueSatTable>| match t {
|
||||||
Some(t) => [
|
Some(t) => [
|
||||||
@@ -706,7 +706,7 @@ mod tests {
|
|||||||
fn the_buffer_puts_the_header_first_and_the_look_after_the_hue_sat_map() {
|
fn the_buffer_puts_the_header_first_and_the_look_after_the_hue_sat_map() {
|
||||||
let bare = profile_buffer(None);
|
let bare = profile_buffer(None);
|
||||||
assert_eq!(bare[..2], [[0.0; 4]; 2], "no tables");
|
assert_eq!(bare[..2], [[0.0; 4]; 2], "no tables");
|
||||||
assert_eq!(bare[2][0], 1025.0, "and Camera Raw's default curve");
|
assert_eq!(bare[2][0], 1025.0, "and the reference default curve");
|
||||||
assert_eq!(bare.len(), HEADER_ENTRIES + 1025);
|
assert_eq!(bare.len(), HEADER_ENTRIES + 1025);
|
||||||
let t = tables(
|
let t = tables(
|
||||||
Some(uniform(2, 2, 1, [1.0, 2.0, 3.0])),
|
Some(uniform(2, 2, 1, [1.0, 2.0, 3.0])),
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ pub const WHITE: ParamId = ParamId("white");
|
|||||||
/// TRACES: FR-DEV-3j
|
/// TRACES: FR-DEV-3j
|
||||||
/// Which curve renders: D19's sigmoid (index 0, the default) or Camera
|
/// Which curve renders: D19's sigmoid (index 0, the default) or Camera
|
||||||
/// Raw's (D21). Which of the two should be the default is open — the
|
/// Raw's (D21). Which of the two should be the default is open — the
|
||||||
/// Lightroom-matching work decides it — so the default is what 0.20.0
|
/// measurement work decides it — so the default is what 0.20.0
|
||||||
/// rendered.
|
/// rendered.
|
||||||
pub const CURVE: ParamId = ParamId("curve");
|
pub const CURVE: ParamId = ParamId("curve");
|
||||||
|
|
||||||
@@ -161,7 +161,7 @@ impl Operation for ViewTransform {
|
|||||||
"\
|
"\
|
||||||
// Skipped for an already-rendered source: a JPEG is a display rendering
|
// Skipped for an already-rendered source: a JPEG is a display rendering
|
||||||
// already, and rendering it again would compress it twice.
|
// already, and rendering it again would compress it twice.
|
||||||
// D19's sigmoid by default, Camera Raw's tone by choice (D21).
|
// D19's sigmoid by default, the DNG reference tone by choice (D21).
|
||||||
if (!non_linear) {
|
if (!non_linear) {
|
||||||
if (mode > 0.5) {
|
if (mode > 0.5) {
|
||||||
c = camera_raw_tone(c, cr_scale, cr_power, cr_grey);
|
c = camera_raw_tone(c, cr_scale, cr_power, cr_grey);
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ pub struct ProfileTables {
|
|||||||
pub look: Option<HueSatTable>,
|
pub look: Option<HueSatTable>,
|
||||||
/// The profile's `ProfileToneCurve`, resampled onto
|
/// The profile's `ProfileToneCurve`, resampled onto
|
||||||
/// [`crate::tone::TONE_SAMPLES`] points; `None` where it has none, and
|
/// [`crate::tone::TONE_SAMPLES`] points; `None` where it has none, and
|
||||||
/// the view transform's Camera Raw curve then uses
|
/// the view transform's DNG reference curve then uses
|
||||||
/// [`crate::tone::ACR3_DEFAULT`] (D21).
|
/// [`crate::tone::ACR3_DEFAULT`] (D21).
|
||||||
pub tone_curve: Option<Vec<f32>>,
|
pub tone_curve: Option<Vec<f32>>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
//! TRACES: FR-DEV-3j | FR-DEV-3e
|
//! TRACES: FR-DEV-3j | FR-DEV-3e
|
||||||
//! Camera Raw's tone curves, as data (D21).
|
//! The DNG SDK's reference tone curve, as data (D21).
|
||||||
//!
|
//!
|
||||||
//! # Where the numbers come from
|
//! # Where the numbers come from
|
||||||
//!
|
//!
|
||||||
//! [`ACR3_DEFAULT`] is the "ACR3 default" tone curve of Adobe's DNG SDK
|
//! [`ACR3_DEFAULT`] is the "ACR3 default" tone curve of Adobe's DNG SDK
|
||||||
//! (`dng_tone_curve_acr3_default`): what Camera Raw renders a raw through
|
//! (`dng_tone_curve_acr3_default`): what the SDK's reference renders a raw through
|
||||||
//! when its camera profile carries no `ProfileToneCurve` of its own, which is
|
//! when its camera profile carries no `ProfileToneCurve` of its own, which is
|
||||||
//! true of Adobe Standard. The values are RawTherapee's
|
//! true of Adobe Standard. The values are RawTherapee's
|
||||||
//! `adobe_camera_raw_default_curve` (`rtengine/dcp.cc`, GPLv3), copied
|
//! `adobe_camera_raw_default_curve` (`rtengine/dcp.cc`, GPLv3), copied
|
||||||
|
|||||||
+35
-14
@@ -95,7 +95,7 @@ Two departures, both forced by D19's unbounded scene-linear values (the SDK runs
|
|||||||
both tables, which is where the second reason matters:
|
both tables, which is where the second reason matters:
|
||||||
- **The look sees exposure.** The SDK applies `LookTable` after its exposure ramp, so a look that
|
- **The look sees exposure.** The SDK applies `LookTable` after its exposure ramp, so a look that
|
||||||
desaturates highlights finds the highlights the photographer chose. At 25 it does too. Contrast,
|
desaturates highlights finds the highlights the photographer chose. At 25 it does too. Contrast,
|
||||||
tone and the colour controls come after it, as they do in Camera Raw.
|
tone and the colour controls come after it, as they do in the DNG SDK's reference rendering.
|
||||||
|
|
||||||
**Tables are per source, like the matrix.** They are decoded with the raw, interpolated once at
|
**Tables are per source, like the matrix.** They are decoded with the raw, interpolated once at
|
||||||
decode (the HueSatMap blend uses the as-shot neutral, as the matrix does) and carried on
|
decode (the HueSatMap blend uses the as-shot neutral, as the matrix does) and carried on
|
||||||
@@ -151,7 +151,7 @@ reads a buffer no declaration can name:
|
|||||||
| Parameter | Kind | Default | Meaning |
|
| Parameter | Kind | Default | Meaning |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `apply` | Bool | on | Use the profile's tables, or the matrix alone |
|
| `apply` | Bool | on | Use the profile's tables, or the matrix alone |
|
||||||
| `look` | Scalar 0–200 | 100 | Strength of the `LookTable`, as Lightroom's *Amount* |
|
| `look` | Scalar 0–200 | 100 | Strength of the `LookTable` |
|
||||||
|
|
||||||
`look` scales the look's deltas: `hueShift · a`, `1 + (satScale − 1)·a`, `1 + (valScale − 1)·a`,
|
`look` scales the look's deltas: `hueShift · a`, `1 + (satScale − 1)·a`, `1 + (valScale − 1)·a`,
|
||||||
with `a = look/100`, scales floored at 0. At 200 the look is twice as strong, which is the
|
with `a = look/100`, scales floored at 0. At 200 the look is twice as strong, which is the
|
||||||
@@ -277,14 +277,14 @@ correction to it. The DNG SDK's total is their sum, and so is this one's.
|
|||||||
baseline, and matches a copied `.dcp` counts the baseline twice. Every Adobe-written DNG embeds
|
baseline, and matches a copied `.dcp` counts the baseline twice. Every Adobe-written DNG embeds
|
||||||
its profile, so that DNG is a hand-made one.
|
its profile, so that DNG is a hand-made one.
|
||||||
|
|
||||||
## 12. Camera Raw tone (D21)
|
## 12. DNG reference tone (D21)
|
||||||
|
|
||||||
Lightroom's richer colour is its tone curve (§1). Camera Raw renders a raw through the profile's
|
The DNG SDK's reference rendering runs a raw through the profile's
|
||||||
`ProfileToneCurve`, or, for a profile that has none — Adobe Standard among them — through the
|
`ProfileToneCurve`, or, for a profile that has none — Adobe Standard among them — through the
|
||||||
*ACR3 default curve*, a 1025-point table published in the DNG SDK and carried by RawTherapee
|
*ACR3 default curve*, a 1025-point table published in the DNG SDK and carried by RawTherapee
|
||||||
(GPLv3) as `adobe_camera_raw_default_curve`.
|
(GPLv3) as `adobe_camera_raw_default_curve`.
|
||||||
|
|
||||||
**How it is applied** is half of what it does. Camera Raw does not run the curve on each channel:
|
**How it is applied** is half of what it does. The reference does not run the curve on each channel:
|
||||||
`RefBaselineRGBTone` runs it on the largest and smallest channel and places the middle one at the
|
`RefBaselineRGBTone` runs it on the largest and smallest channel and places the middle one at the
|
||||||
same fraction between them as before. Hue is kept; saturation rises where the curve is steep —
|
same fraction between them as before. Hue is kept; saturation rises where the curve is steep —
|
||||||
the shadows and midtones — which is exactly where Adobe Standard's look table desaturated to
|
the shadows and midtones — which is exactly where Adobe Standard's look table desaturated to
|
||||||
@@ -296,25 +296,25 @@ that rendering, chosen by a new parameter on `view_transform`:
|
|||||||
| `curve` | What it is | Default for |
|
| `curve` | What it is | Default for |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Sigmoid | D19's log-logistic curve | every raw, for now |
|
| Sigmoid | D19's log-logistic curve | every raw, for now |
|
||||||
| Camera Raw | the profile's curve, else ACR3, via RGBTone in ProPhoto | — (D21: the default is open) |
|
| DNG reference | the profile's curve, else ACR3, via RGBTone in ProPhoto | — (D21: the default is open) |
|
||||||
|
|
||||||
*Amended 2026-10-03:* Camera Raw was the default in the first draft. The measurement it rested on
|
*Amended 2026-10-03:* the DNG reference was the default in the first draft. The measurement it rested on
|
||||||
compared against Lightroom renders of *edited* photographs; see D21. The default is decided by
|
compared against Lightroom renders of *edited* photographs; see D21. The default is decided by
|
||||||
measuring against Lightroom exports of unedited ones.
|
measuring against Lightroom exports of unedited ones.
|
||||||
|
|
||||||
A JPEG is still not rendered again (FR-DEV-3j). Film simulation still replaces the view transform
|
A JPEG is still not rendered again (FR-DEV-3j). Film simulation still replaces the view transform
|
||||||
when a stock is chosen.
|
when a stock is chosen.
|
||||||
|
|
||||||
**The two sliders keep meaning something** under Camera Raw:
|
**The two sliders keep meaning something** under the DNG reference curve:
|
||||||
|
|
||||||
- `white` (stops above grey at which the scene reaches display white) sets the input scale:
|
- `white` (stops above grey at which the scene reaches display white) sets the input scale:
|
||||||
`2^(4 − white)`. At its default of 4 the scale is 1 — sensor white is display white, as in
|
`2^(4 − white)`. At its default of 4 the scale is 1 — sensor white is display white, as in
|
||||||
Camera Raw.
|
the SDK's reference.
|
||||||
- `contrast` bends the input about middle grey before the curve, as a power of
|
- `contrast` bends the input about middle grey before the curve, as a power of
|
||||||
`contrast / 1.4`: 1 at its default, so the curve is Camera Raw's untouched.
|
`contrast / 1.4`: 1 at its default, so the curve is the reference's untouched.
|
||||||
|
|
||||||
**What the ACR curve gives up** is D19's shoulder. Values above display white clip, as they do
|
**What the ACR curve gives up** is D19's shoulder. Values above display white clip, as they do
|
||||||
in Camera Raw; highlight recovery is the highlights slider's job before it. Sigmoid stays one
|
in the SDK's reference; highlight recovery is the highlights slider's job before it. Sigmoid stays one
|
||||||
click away for a photograph that wants the shoulder.
|
click away for a photograph that wants the shoulder.
|
||||||
|
|
||||||
**A profile's own curve** is a list of `(x, y)` pairs. It is resampled at decode onto the same
|
**A profile's own curve** is a list of `(x, y)` pairs. It is resampled at decode onto the same
|
||||||
@@ -323,7 +323,7 @@ identity is treated as absent, as RawTherapee does.
|
|||||||
|
|
||||||
**On the GPU** the curve rides in the profile buffer (`@binding(8)`) after the tables: a third
|
**On the GPU** the curve rides in the profile buffer (`@binding(8)`) after the tables: a third
|
||||||
header entry gives its length, then the samples. The placeholder bound for a source without a
|
header entry gives its length, then the samples. The placeholder bound for a source without a
|
||||||
profile carries the ACR3 curve, so a CR2 with no `.dcp` still renders through Camera Raw's tone.
|
profile carries the ACR3 curve, so a CR2 with no `.dcp` renders through the reference tone when that curve is chosen.
|
||||||
|
|
||||||
## 13. Profiles sync
|
## 13. Profiles sync
|
||||||
|
|
||||||
@@ -355,8 +355,8 @@ its parent, as it excludes the trash.
|
|||||||
- RGBTone: grey goes through the curve unchanged in hue; a colour keeps its hue (the middle
|
- RGBTone: grey goes through the curve unchanged in hue; a colour keeps its hue (the middle
|
||||||
channel's fraction between the outer two is unchanged); a curve that is the identity changes
|
channel's fraction between the outer two is unchanged); a curve that is the identity changes
|
||||||
nothing; the shader agrees with the CPU reference on a device.
|
nothing; the shader agrees with the CPU reference on a device.
|
||||||
- Camera Raw is the default curve for a raw; Sigmoid at the defaults renders to the bit what 0.20.0
|
- Sigmoid is the default curve; at its defaults it renders to the bit what 0.20.0 rendered,
|
||||||
rendered without baseline exposure.
|
apart from baseline exposure.
|
||||||
- A DNG with `BaselineExposure` +0.25 renders a flat grey 0.25 EV brighter than the same pixels
|
- A DNG with `BaselineExposure` +0.25 renders a flat grey 0.25 EV brighter than the same pixels
|
||||||
with none; a `.dcp` copied from it carries `BaselineExposureOffset` 0.25 and gives a CR2 the same
|
with none; a `.dcp` copied from it carries `BaselineExposureOffset` 0.25 and gives a CR2 the same
|
||||||
total.
|
total.
|
||||||
@@ -365,3 +365,24 @@ its parent, as it excludes the trash.
|
|||||||
parsed and matched on the next decode; a file of the same name and size is left alone.
|
parsed and matched on the next decode; a file of the same name and size is left alone.
|
||||||
- Measured again on `_MG_9080`: mean saturation at defaults closer to Lightroom's 0.49 than 0.20.0's
|
- Measured again on `_MG_9080`: mean saturation at defaults closer to Lightroom's 0.49 than 0.20.0's
|
||||||
0.35.
|
0.35.
|
||||||
|
|
||||||
|
## 15. The photographer's earlier edit
|
||||||
|
|
||||||
|
What §1 and D21 first took for a difference in rendering is an edit. Every DNG in the library
|
||||||
|
carries, in its embedded XMP, the develop settings it was given before it came to DarkRoom — a
|
||||||
|
consistent house style: per-colour saturation (blue +58, aqua +50, yellow and purple +23, orange
|
||||||
|
+13, green +10), highlights −40, blacks −20, with a second variant (vibrance −10, blue +31). Those
|
||||||
|
settings, not the profile and not the tone curve, are why the same photographs looked richer
|
||||||
|
before.
|
||||||
|
|
||||||
|
- **Translated on open** (`dr_preset_xmp::read_embedded`), the HSL bands onto the colour mixer —
|
||||||
|
aqua to cyan and purple to violet, the nearest of its twelve by hue — and the rest as the preset
|
||||||
|
importer already did.
|
||||||
|
- **Applied only to a photograph DarkRoom has no edit of**, and only on positive evidence: no
|
||||||
|
sidecar beside a local file, or a server that answered "no such file" with nothing cached
|
||||||
|
(`FetchedSidecar::absent`). An edit that failed to arrive is not an absent one, and this would
|
||||||
|
otherwise be saved over it.
|
||||||
|
- **One undoable step, "Earlier Edit"**, then an ordinary edit, saved with the photograph. Export
|
||||||
|
applies it the same way, so a photograph never opened exports as opening it would show.
|
||||||
|
- **The translation is one for one for now.** Measurement against the earlier exports (the
|
||||||
|
`lr-fit` work) may scale individual bands.
|
||||||
|
|||||||
@@ -2437,7 +2437,7 @@ Rationale, evidence, and the eliminated alternatives are recorded in
|
|||||||
| D12 | Scope versus pace | **DECIDED 2026-09-19** — settled by events; full scope stands, no v1 date |
|
| D12 | Scope versus pace | **DECIDED 2026-09-19** — settled by events; full scope stands, no v1 date |
|
||||||
| D18 | Derived images | **DECIDED 2026-09-19** — a merge writes a new source file; no multi-source Version |
|
| D18 | Derived images | **DECIDED 2026-09-19** — a merge writes a new source file; no multi-source Version |
|
||||||
| D19 | Scene-referred pipeline | **DECIDED 2026-09-27** — edits on unbounded scene-linear colour; one view transform, last; per-body base curves retired |
|
| D19 | Scene-referred pipeline | **DECIDED 2026-09-27** — edits on unbounded scene-linear colour; one view transform, last; per-body base curves retired |
|
||||||
| D21 | Camera Raw tone for raws | **PARTLY DECIDED 2026-10-03** — the view transform gains a Camera Raw curve (profile's, else ACR3 default, via RGBTone in ProPhoto) as a choice; which curve is the default is open, pending measurement against Lightroom exports |
|
| D21 | DNG reference tone for raws | **PARTLY DECIDED 2026-10-03** — the view transform gains the DNG reference curve (profile's, else ACR3 default, via RGBTone in ProPhoto) as a choice; which curve is the default is open, pending measurement against Lightroom exports |
|
||||||
| D20 | DCP camera profiles | **DECIDED 2026-10-02** — HueSatMap and LookTable as a scene operation after exposure; embedded profile first, then a matched `.dcp`; tone curve not applied; none shipped |
|
| D20 | DCP camera profiles | **DECIDED 2026-10-02** — HueSatMap and LookTable as a scene operation after exposure; embedded profile first, then a matched `.dcp`; tone curve not applied; none shipped |
|
||||||
|
|
||||||
### D11 — product positioning
|
### D11 — product positioning
|
||||||
@@ -2773,7 +2773,7 @@ matrix does.
|
|||||||
*What it costs.* Every DNG with an embedded profile renders differently; previews refresh only when
|
*What it costs.* Every DNG with an embedded profile renders differently; previews refresh only when
|
||||||
rendered again; tablet and desktop release together. The profiles directory does not sync yet.
|
rendered again; tablet and desktop release together. The profiles directory does not sync yet.
|
||||||
|
|
||||||
### D21 — Camera Raw tone for raws · **PARTLY DECIDED 2026-10-03**
|
### D21 — DNG reference tone for raws · **PARTLY DECIDED 2026-10-03**
|
||||||
|
|
||||||
*Amended the same day:* the default is **not** decided. The measurement below was against
|
*Amended the same day:* the default is **not** decided. The measurement below was against
|
||||||
Lightroom previews of photographs carrying the user's Lightroom edits — a house look of HSL
|
Lightroom previews of photographs carrying the user's Lightroom edits — a house look of HSL
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -213,9 +213,8 @@ fn catalogued(key: &str) -> Option<&'static str> {
|
|||||||
// the pipeline, and the photographer is choosing how the scene's range
|
// the pipeline, and the photographer is choosing how the scene's range
|
||||||
// is fitted onto the screen.
|
// is fitted onto the screen.
|
||||||
"op.view_transform" => "Tone Mapping",
|
"op.view_transform" => "Tone Mapping",
|
||||||
// The DNG camera profile's tables (D20). "Camera Profile", as Camera
|
// The DNG camera profile's tables (D20). "Camera Profile", the DNG
|
||||||
// Raw calls the same thing, so a photographer arriving from Lightroom
|
// specification's own name for what the file carries.
|
||||||
// finds it under the name they know.
|
|
||||||
"op.camera_profile" => "Camera Profile",
|
"op.camera_profile" => "Camera Profile",
|
||||||
|
|
||||||
// Parameters
|
// Parameters
|
||||||
@@ -226,15 +225,15 @@ fn catalogued(key: &str) -> Option<&'static str> {
|
|||||||
"param.learned_denoise.apply" => "Apply",
|
"param.learned_denoise.apply" => "Apply",
|
||||||
"param.learned_denoise.grain" => "Keep grain",
|
"param.learned_denoise.grain" => "Keep grain",
|
||||||
"param.camera_profile.apply" => "Use Profile",
|
"param.camera_profile.apply" => "Use Profile",
|
||||||
// The LookTable's strength, as Lightroom's profile "Amount".
|
// The LookTable's strength.
|
||||||
"param.camera_profile.look" => "Look Amount",
|
"param.camera_profile.look" => "Look Amount",
|
||||||
"param.view_transform.contrast" => "Contrast",
|
"param.view_transform.contrast" => "Contrast",
|
||||||
// In stops above middle grey: where the scene reaches display white.
|
// In stops above middle grey: where the scene reaches display white.
|
||||||
"param.view_transform.white" => "White Point",
|
"param.view_transform.white" => "White Point",
|
||||||
// The view transform's curve (D21): Camera Raw's tone, as Lightroom
|
// The view transform's curve (D21): the DNG SDK's reference
|
||||||
// renders a raw, or D19's sigmoid with its highlight shoulder.
|
// rendering, or D19's sigmoid with its highlight shoulder.
|
||||||
"param.view_transform.curve" => "Curve",
|
"param.view_transform.curve" => "Curve",
|
||||||
"param.view_transform.curve.camera_raw" => "Camera Raw",
|
"param.view_transform.curve.camera_raw" => "DNG Reference",
|
||||||
"param.view_transform.curve.sigmoid" => "Sigmoid",
|
"param.view_transform.curve.sigmoid" => "Sigmoid",
|
||||||
"param.temperature" => "Temperature",
|
"param.temperature" => "Temperature",
|
||||||
"param.tint" => "Tint",
|
"param.tint" => "Tint",
|
||||||
|
|||||||
Reference in New Issue
Block a user