HDR Highlight Compression on the GPU: a NaN Amount keeps the layer, as on the CPU

Doc comments on the touched helpers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
vangel76andClaude Opus 5.5 committed 2026-11-05 18:11:29 +01:00
1 parent af7044d7db
commit 3a9188e0fb
3 files changed
+9 -1

No files matched your search

+3
View File
@@ -60,6 +60,7 @@ const HDR_LUMA: [f32; 3] = [0.30, 0.59, 0.11];
/// Exponent of the domain the Amount blend happens in (out^0.4 is mixed linearly).
const HDR_BLEND_GAMMA: f32 = 0.4;
/// `v^e` with the sign of `v` kept (negative input stays negative, as on the GPU).
#[inline]
fn hdr_spow(v: f32, e: f32) -> f32 {
v.signum() * v.abs().powf(e)
@@ -82,6 +83,8 @@ fn hdr_compress_pixel(c: [f32; 3], t: f32) -> [f32; 3] {
})
}
/// HDR Highlight Compression: every straight-colour pixel through [`hdr_compress_pixel`] at
/// Amount / 100; Amount 0 or NaN returns the layer unchanged.
fn hdr_compression(ctx: &EffectCtx, mut b: Buf) -> Buf {
let t = (ctx.params.f("amount") / 100.0).clamp(0.0, 1.0) as f32;
if t <= 0.0 || !t.is_finite() {
+4 -1
View File
@@ -215,6 +215,8 @@ fn composite_mode(m: u32) -> BlendMode {
}
}
/// The per-pixel effects of `fp2_point` (Cineon, HDR Compander and Highlight Compression, CC
/// Overbrights, CC Composite, Color Link): their parameters packed for the kernel, or `None`.
fn point(e: &mut Enc, id: &str, ctx: &EffectCtx, b: GBuf) -> Option<GBuf> {
let pr = ctx.params;
let mut p = Params::default();
@@ -238,7 +240,8 @@ fn point(e: &mut Enc, id: &str, ctx: &EffectCtx, b: GBuf) -> Option<GBuf> {
}
"ec.utility.hdrcompression" => {
let t = (pr.f("amount") / 100.0).clamp(0.0, 1.0) as f32;
if t <= 0.0 {
// A NaN Amount keeps the layer, as on the CPU.
if t <= 0.0 || !t.is_finite() {
return Some(b);
}
p.u[0][0] = 2;
+2
View File
@@ -185,6 +185,8 @@ fn composites_and_colour() {
effect_case("ec.utility.hdrcompression", &[]);
effect_case("ec.utility.hdrcompression", &[("amount", n(40.0))]);
effect_case("ec.utility.hdrcompression", &[("amount", n(90.0))]);
// A NaN Amount keeps the layer (the CPU returns it unchanged).
effect_case("ec.utility.hdrcompression", &[("amount", n(f64::NAN))]);
effect_case("ec.utility.growbounds", &[("pixels", n(9.0))]);
effect_case("ec.utility.ccoverbrights", &[]);
for ch in 1..=5 {