The look everybody wants from film does not live in the film. It lives in a machine, and the machines are going away.
A Frontier is a minilab scanner from the era when a high street needed one. The colour it hands back was never a filter somebody designed to be pretty — it is what a shop had to give a stranger, without being asked and without a second try. That is why it still looks right to us. It was tuned by people who could not afford to be interesting.
You can chase that look by eye forever. Or you can go and find out what the machine actually does.
This is the story of trying the second thing, and of everything that went wrong on the way.
#What is actually inside a Frontier
Almost nothing you would guess.
The optics are the boring part. What makes a Frontier picture look like a Frontier picture happens after the scan, in software — a chain of steps, each handing a number to the next. That chain was the target from the beginning. Not the scans it produced. The thing that produced them.
#The decompiler lies to you
To read that chain you take the program apart. The tool that does it is called a decompiler, and a decompiler is a very good liar. It lies most convincingly when it is nearly right.
In one place it showed me a tidy little rounding step. The machine underneath was not rounding at all. It was throwing the fraction away — and the two agree on almost every number you would think to test by hand, then part company exactly where photographs live.
I only caught it by reading the raw instructions instead of the friendly translation. If I had not, every pixel of every frame would have sat one step off, forever, and no comparison loose enough to say "close enough" would ever have shown it.
The second lesson came the same week and was quieter. The tool shows the program's stored numbers as zeros — they simply are not there to read. They had to be dug out of the file itself. And once something has confidently shown you a zero that is not a zero, you stop trusting numbers that merely look sensible.
Important
A constant is never taken because it looks round.
0.5,1.0,255— those are exactly the values a tired person invents at two in the morning and never questions again.
#The day my own notes contradicted me
I write everything down while it happens, not afterwards. That file has run to some nine hundred entries.
My favourite two sit next to each other.
In the first I work through a piece of the machine and conclude — carefully, over four separate lines of attack — that I had been looking at the wrong thing entirely, and that its exact shape did not matter anyway.
The next entry begins by saying that fresh evidence had just landed and overturned it. I had been looking at the right thing all along.
Both entries are still there. I did not go back and quietly tidy the first one into agreement with the second, and that is the single most useful habit I have. Notes that keep only the conclusions read beautifully and are worth nothing, because nobody — including me, a month later — can tell which ideas survived a fight and which were simply never challenged.
#Getting it exactly right, and finding that this was not enough
Eventually the chain came out right. Not roughly: the target was set before the work started — the same picture, from the same scan, indistinguishable at the level of a single step of brightness, on frames deliberately kept out of the fitting — and it was met exactly.
Which felt like the end. It was not.
A program that reproduces a machine by carrying that machine's own numbers around inside it is not something you can put on sale. So the exact copy was frozen and given a different job. It became a reference I could interrogate: what would the machine have done with this? — asked millions of times, and never shipped to anybody.
Then the actual work started: build my own numbers, from scratch, and push them through my own implementation until the reference could no longer tell the difference. Fit the behaviour, never copy the table. And ship none of theirs.
#The cast
The first attempt at that came out with a colour cast. Around three steps of red, two and a half of green, one and a half of blue. Small enough to argue about. Far too large to accept.
It was not a mystery for long, and the cause is the most ordinary mistake in engineering: I had measured something after it had already been corrected, so my correction landed on top of a correction. Measure the thing before the adjustment rather than after it, and the bias goes to nothing.
The other death that week was a hypothesis I badly wanted to be true. The machine's sharpening looked far too elaborate for what it did, and everybody's first guess is that a plain unsharp mask would do the same job in one line. I tested it properly. It was off by ten steps on average and a hundred and nineteen at worst. The elaborate machinery was earning its keep after all.
Refuted, in writing, with the numbers that killed it. Those entries are worth more than the ones where I was right.
#The light you cannot buy
Here is the part that no amount of software will fix, and the part I underestimated most.
To separate the three dyes in a negative you need three narrow bands of light. Not a white lamp, not a "high CRI" lamp, not a screen — three genuinely narrow colours, hitting the film one at a time.
Almost nobody makes that. There is no shelf to take it off. The light in my own rig is an open-source design (jackw01/scanlight) rather than a product, because a product barely exists.
And it gets worse, because the bands you can get are not the bands the scanner used. The Frontier lit film at roughly 545 nm in green and 650 in red. The parts you can actually put your hands on land at 525 and 665. Twenty nanometres out in one channel, fifteen in the other.
To a person that sounds like nothing. To a film dye it is not nothing at all.
That gap does not disappear. It gets paid for, in software, every single frame — it is precisely why the application carries a correction that varies from roll to roll, and a separate calibration for each emulsion. Both of those exist because my lamp sits beside the right colours instead of on them.
The obvious answer is to buy better diodes, and I may yet. But it is not a purchase, it is a rebuild: everything downstream has been fitted around the light I actually have, so changing the light means refitting the whole chain behind it, in order. I have written down how I will judge the new one — the pass and fail conditions, before the first measurement, so I cannot later be talked into a result by my own hopefulness.
The other thing this taught me is how easily a good story beats a true one. My readings drifted between blocks of sessions, and there was an obvious culprit: the lamp warming up. It is such a satisfying explanation. I went and measured it. The lamp was innocent. The drift is real and still booked as a constant, and I would have "solved" it wrongly and confidently if I had trusted the story instead of the meter.
#The wall I cannot move
All of the above is about a scanner's pipeline, checked against a scanner's own output. Putting an ordinary camera capture through it is a different and much harder problem, and white light cannot solve it: under one broad exposure, the film's three dyes are not separable. Different colours arrive as the same three camera numbers, and nothing you do afterwards can pull apart what the light already mixed.
That wall is the whole reason this application asks for three exposures instead of one. The separating is done by the light, before the arithmetic gets a vote. It is also why the hardware problem above is not a detail — it is the foundation. What this application does not do walks the rest of that boundary.
#Why I am telling you all this
Because what you are being asked to trust is colour, and colour is the easiest thing in photography to claim and the hardest to check. "Looks like film" is not a claim. It is a mood.
So here is the trail instead: a named machine, a target written down before the work rather than after it, notes that keep their own refuted entries, and a test suite — six hundred and forty-six of them — that fails the build the moment a number moves.
None of it makes the pictures good. It just means that when the colour is wrong, there is something to measure, and someone who has to answer for it.
Note
The dismantled internals of somebody else's product — addresses, offsets, layouts, their own data files — stay in my analysis repository and are not distributed. That is not modesty. Publishing them would contradict the one sentence here that matters most, which is that what I sell contains none of their numbers.