Two words that often get used as if they meant the same thing, explained with figures you can try and Redlamp's own tone curve.
· Pedro
Redlamp is a free, open-source raw photo editor for the Mac that works like Lightroom. Some feedback I got recently pointed out two things: Redlamp has no scene-referred mode, and in its exports, the L* of a grey scale's patches isn't linear against the chart's own values. Exports of metered shots of a target also came out slightly dark.
Answering that properly meant untangling two words that often get used as if they meant the same thing. They don't. Linear and scene-referred answer different questions about a pixel's numbers, so they aren't opposites: a pixel can be linear and scene-referred, either one, or neither.
This article works through both, with figures you can try. The curves in them are Redlamp's own, as its code has them on 9 October 2026.
Linear
How the numbers are written: twice the light, twice the number.
Scene-referred
Whose light they describe: the light in front of the camera, which has no ceiling, rather than the light a screen gives off, which stops at white.
The tone curve
What turns scene light into screen light. A scene-referred mode, which the feedback asks for, would leave it out, without changing how files are encoded.
Two questions, four combinations
Follow a grey card, at 0.18 in scene light, and a sunlit cloud, at 2.0, into each corner. The same two lights get different numbers in each.
How the numbers are written →
Whose light ↓
Linear
Twice the light, twice the number
Non-linear
A curve: sRGB, gamma or log
Scene-referred
The light in front of the camera; no ceiling
Scene-referred, written linearly
Scene-linear
Redlamp edits here
Proportional to the light in front of the camera, with no ceiling: a street lamp can read 20 while the grey card reads 0.18.
Grey card
0.18
Sunlit cloud
2.00
In Redlamp
White balance, Exposure, the tone sliders, halation and bloom, in linear Rec. 2020.
Elsewhere
A raw file's sensor values, OpenEXR, ACEScg.
Scene-referred, written with a curve
Scene-referred, log-encoded
The same scene light on a log scale: every stop gets an equal share of the numbers, so a wide range fits between 0 and 1.
Grey card
0.606
Sunlit cloud
0.817
In Redlamp
Film looks read their tables from it, over −10 to +6.5 stops around the grey card.
Elsewhere
Camera log video (S-Log3, LogC), ACEScct.
Display-referred
The light the screen gives off; stops at white
Display-referred, written linearly
Display-linear
Proportional to the light the screen gives off. 1.0 is the screen's white and nothing goes above it: the tone curve has already fitted the scene in.
Grey card
0.332
Sunlit cloud
0.999
In Redlamp
Vibrance, Saturation, the Color Mixer, Point Color and Color Grading, in OKLab worked out from this light.
Elsewhere
A TIFF of a finished render saved with linear numbers.
Display-referred, written with a curve
Display-encoded
What JPEGs, PNGs and the screen's signal carry: screen light written with the sRGB curve, which gives the darks more of the 256 levels.
Grey card
156 of 255
Sunlit cloud
255 of 255
In Redlamp
Curves, vignette and grain; then the export and the screen.
Elsewhere
Every JPEG. sRGB and Display P3 share this curve.
Across a row, the light stays the same and only its numbers change: re-encoding is arithmetic, exact in both directions. Down a column, the light itself changes: the tone curve decides how the scene's range fits between black and the screen's white, and whatever it presses into white can't be told apart afterwards. The cloud's 2.00 has nowhere to go on a screen but 0.999.
Linear: how the numbers are written
Light adds up: two lamps give twice the light of one. Linear numbers keep that proportion, so the arithmetic of light works on them directly: a stop of Exposure is ×2, and a blur averages light. Eyes don't see light that way: the step from 1% to 2% of white looks about as big as the step from 50% to 100%. So files and screens write light with a curve that gives the darks more numbers. Converting between the two is a formula, exact both ways: it changes the numbers, not the picture.
Stored value for each amount of light
Three ways of writing the same light, from black to white. Drag the light to compare them.
LinearsRGB curveL* curve (eciRGB v2): L* ÷ 100
Light: 18.0% of white, 2.47 stops below it
Written as
Stored value
8-bit level
Linear
0.180
46
sRGB curve (sRGB, Display P3)
0.461
118
L* curve (eciRGB v2)
0.495
126
Middle grey, 18% of white, is 46 of 255 written linearly, 118 with the sRGB curve and 126 with the L* curve that eciRGB v2 uses. L* is also the scale the feedback measured in: 18% of white is L* 49.5, near the middle, which is about where it looks.
8-bit levels in each stop below white
How many of an 8-bit file's 256 levels fall in each stop, written linearly and with the sRGB curve.
LinearsRGB curve
Linear spends half of its 256 levels on the brightest stop and leaves 2 for the seventh, where shadows would band; the sRGB curve spreads them out. Redlamp computes in floating point, where linear numbers lose nothing.
Light adds; stored numbers don't
Half black, half white: what's the average?
Black and white lines
half of white's light
188 of 255
averaging the light: 50%
128 of 255
averaging the numbers: 22%
Step back or squint: the lines blend into the middle patch, not the right one. A blur, resize or blend done on sRGB-encoded numbers makes mixes too dark, and leaves dark fringes around bright edges. View at 100% zoom.
Linear is a property of the numbers, not of the light. The same light can be written linearly, with the sRGB curve, with gamma 1.8 or on a log scale, and a colour-managed reader gets the same light back from each. So whether a file is linear says nothing about whose light it holds. That's the second question.
Scene-referred: whose light the numbers describe
A scene-referred number describes the light that was in front of the camera, relative to the rest of the scene: if a grey card is 0.18, a sunlit cloud is about 2 and a street lamp about 20. There's no ceiling, because scenes have none. A display-referred number describes the light a screen should give off, and 1.0 is the screen's white.
Getting from one to the other means deciding how the scene's range fits between the screen's black and white. That decision is the tone curve: a choice, not arithmetic, and different curves make different pictures of the same scene.
Exposure playground
An illustrative scene, from a deep shadow to a street lamp. Exposure multiplies every scene value, so dragging it slides every object along the scale.
Exposure 0.0 EV: every scene value × 1.00
Compare with
Exposure, then Redlamp's tone curveThe tone curve, then Exposure
Deep shadow
Dark coat
Grey card
White paper
Sunlit cloud
Street lamp
Scene value
After Exposure; above 1.0 in colour
0.008
0.040
0.18
0.80
2.00
20.0
Exposure, then the curve
Scene-referred editing, as Redlamp does it; L* under each patch
3
23
64
97
99.9
white
The curve, then Exposure
Editing the finished render
3
23
64
97
99.9
white
Try −2: with Exposure first, the cloud comes back (L* 90) and the lamp stays white. With Exposure after the curve, both had already been written as white, or within a hair of it, so they darken to the same flat grey (L* 57 and L* 57): the curve threw away the difference between 2 and 20. Try +2: with Exposure first, the grey card rolls off to L* 96; after the curve, it clips to white. Redlamp applies Exposure first, in scene light.
Where Redlamp does each
One render passes through all four corners of the grid, in this order. Every change of encoding on the way is exact. The one change of reference is stage 2, the tone curve, which a scene-referred mode would replace with scene light copied straight up to white.
One render, in order
Each stage marked by the light it describes and how its numbers are written.
Describes
Scene
Scene → display
Display
Written as
Linear
Log, for film looks
Linear
sRGB curve
Stage
1Develop
White balance, the camera's colour, Exposure (a multiply), halation and bloom (light added), the tone sliders, black and white points.
2Tone curve
Scene light to screen light, reaching white at 2.88, 4 stops over the grey card. A film look takes its place, reading a log encoding of the scene.
3Colour
Vibrance, Saturation, the Color Mixer, Point Color and Color Grading, in OKLab worked out from linear light.
4Finishing
Curves, vignette, grain, light leaks and the frame, on values written with the sRGB curve.
5Output
Fitted into sRGB or Display P3, which share the sRGB curve, for the screen, JPEG and TIFF.
Scene · Linear
1Develop
White balance, the camera's colour, Exposure (a multiply), halation and bloom (light added), the tone sliders, black and white points.
Scene → display · Log, for film looks
2Tone curve
Scene light to screen light, reaching white at 2.88, 4 stops over the grey card. A film look takes its place, reading a log encoding of the scene.
Display · Linear
3Colour
Vibrance, Saturation, the Color Mixer, Point Color and Color Grading, in OKLab worked out from linear light.
Display · sRGB curve
4Finishing
Curves, vignette, grain, light leaks and the frame, on values written with the sRGB curve.
Display · sRGB curve
5Output
Fitted into sRGB or Display P3, which share the sRGB curve, for the screen, JPEG and TIFF.
Source: the order in Develop.metal, the Metal shader that renders every edit.
The colour controls sit after the curve on purpose. There, Saturation and Vibrance know how close each colour already is to the edge of what the output can show, so they hold hue and clip nothing. How Redlamp handles raw files describes everything before the develop stage, from the file on disk to the camera colour it starts from.
What the feedback asked for
The feedback measured a grey scale: plotted against each patch's reference L*, the L* in Redlamp's export bends away from a straight line. Two meanings of "linear" meet in that sentence.
Linear numbers
Values proportional to light, as in Redlamp's working space. They say nothing about the tone curve: today's render saved as a TIFF with linear numbers would fail the same check as the sRGB export, because those numbers hold screen light, curve and all.
Linear response
Screen light proportional to scene light up to white, with no curve bending it. Then every patch's L* lands on its reference, a straight line with a slope of 1, whatever curve the file is written with, because L* is measured after decoding. This is what the feedback is asking for.
A ColorChecker's grey row through Redlamp's tone curve
A linear response is the dashed diagonal: every patch at its own L*. Drag Exposure, or anchor middle grey, and try to put all six on it. Redlamp Neutral and Redlamp Color are two of its built-in looks; Neutral has the lower contrast.
Exposure 0.00 EV: an 18% grey sits at 0.180 in scene light
Linear response: no curveRedlamp Neutral
Patch
Chart, render
Ref
Render
Gap
Black 2
20.5
24.2
+3.7
Neutral 3.5
35.7
46.4
+10.7
Neutral 5
50.9
65.9
+15.0
Neutral 6.5
66.8
80.7
+13.9
Neutral 8
81.3
89.5
+8.2
White 9.5
96.5
95.2
−1.3
+15.0
Largest gap in L*, at Neutral 5
Anchoring puts Neutral 5 on its reference, but the curve's toe still pulls the dark patches down and its shoulder pulls White down: no exposure puts all six on the diagonal. A reproduction mode has to replace the curve, not adjust it.
Model: Redlamp's tone curve with each look's contrast, as greyscale.py models it, with each patch's scene value at its reflectance × 2Exposure, so 0 EV puts an 18% grey at 0.18. Anchored under Neutral, it gives White 86.9, Neutral 8 78.4 and Black 15.0. Redlamp's renders of a CC0 raw of a ColorChecker from a Sigma fp, anchored the same way, measured 86.3, 78.1 and 17.3: flare in a real photo lifts the black. Reference L*: BabelColor's averages for the ColorChecker.
What would fix it
A scene-referred mode fixes the shape. It's a rendering with no tone curve and no look: screen light equals scene light up to white. In the figure above, the curve becomes the diagonal, and once exposure is anchored, a metered 18% grey reads L* 49.5. Its exports can keep an ordinary curve, sRGB or a reference space for archive masters: their numbers aren't linear, but the light they describe is the scene's.
Tying exposure to each camera's metering fixes the position. Redlamp scales each sensor's clip point to 1.0, and cameras put a metered 18% grey roughly 3.3 to 3.7 stops below clip, depending on how each maker calibrates ISO. Redlamp only adds a baseline exposure for DNG files, which carry one; other raws get none. So Exposure 0 means a different grey on each camera, which would explain exports coming out slightly dark. Anchoring slides the line along; it doesn't straighten it.
Neither exists in Redlamp yet.
In one line
Linear is how the numbers are written; scene-referred is whose light they describe. Redlamp edits scene-linear, renders through the tone curve and writes display-encoded files. The feedback asks for files that still describe the scene: that's a change of rendering and of how exposure is anchored, not of encoding.
The tone curve, its constants and the render order are Develop.metal's. The grey-scale model is greyscale.py's, which also measures Redlamp's renders of chart raws. The sRGB curve is IEC 61966-2-1's, and the lightness scale is CIE 1976 L*.