# Light Meter — provenance

**What this is.** A standalone tool in the Tools room (`/tools/light-meter/`, short host
`light.artwaste.land`): a photographic light meter. Point a camera at a scene and it returns
an exposure value and an ISO / shutter / aperture combination that will expose it; turn any
one of the three and the other two move to hold the exposure.

**The engine.** The files below are a **byte-for-byte copy** of the engine in
[artwasteland/light-meter](https://github.com/artwasteland/light-meter), which is the
canonical repository and is public. The copy is kept identical on purpose, so that the file
the tool runs is the file the tests and the bench check. This follows the Tools-room
precedent set by Easy Batch Prompting and Sky Now.

```
analysis.js          7820a4637dbdf91c4e707790093470a0a99a5f1bbf56e0d8603e72513fa5a966
exposure.js          10adda7b792d5a4a182aac60f4ca5bcb64afa55898c41e8c5353866af22a7bf2
scales.js            ed2b77fdb6d1a4301df33e55161fee4b810d273cbf185433034a486dc1fe4c40
calibration.js       ce046f9354c2d85b67cc2a01e4d2b13f65802cb7620f1a80e04356e7484704ef
exif.js              bd97cf1ec23043b6ccad0690912c9c6468b4f7362fc2a45360e6b0f7a8a2ae51
capture.js           5426555edca229fe35825d9507f223962ff62e8ad2b1abccb9b71480a80ee2f3
meter.js             765eb5e21078c34bafe9dbac969cdaca8254a6644da3c014088c056dcbdaab78
presets.js           8c4b1aee68e24d78fe6307d815d21e643bba8d8244cc0c3b6f1434c095e29f66
store.js             15f56c34cd58ace95445808c6c33993342e2473676a7ac438075c037a7ea6f82
ui/dial.js           997504edef5c6dbeb40e33ea89a6223479aa66c4d8fef4489d877e39b545b02d
ui/zone-strip.js     f6902d04a370de7807d30467e2c53480ccd1047c0c2cb72c27e599e66bd45007
```

`verify-light-meter.mjs` recomputes these and fails if any copy has drifted.

**Why the source is public.** The tool reads your camera and uploads nothing. That is a
claim, and a claim about privacy is worth exactly what the reader's ability to check it is
worth, so the code making it is readable in full.

## The check (show-the-check)

Two independent checks, covering different things.

**`npm test` in the canonical repository** covers the mathematics, which is where being
wrong would be quiet and expensive: the sixth-stop lattice against the textbook exposure
equation, the compensation and locking rules, cascading when a parameter runs out of range,
the signs of zone placement and compensation, reciprocity, every engraved label on every
dial at every click size, the EXIF reader against bytes it builds itself, and the
calibration gates.

**`research/light-meter/bench.mjs` in this repository** covers what the instrument may
*claim*, which no unit test can. It runs the whole chain over synthetic scenes whose true
answer is known by construction and measures where it breaks. It set every gate in
`calibration.js`, and it changed the design twice.

- **The browser resamples in the wrong space.** Drawing a frame into a smaller canvas
  box-filters the gamma-encoded bytes, and averaging encoded values is not averaging light.
  Measured, that is a systematic under-read reaching 0.95 stops on a twelve-stop scene,
  always in the same direction, so it never averages out across references however many are
  taken. The frame is point-sampled instead, which averages nothing and so cannot acquire
  the bias: worst case 0.12 stops, varying in sign, so that one does cancel.
- **The mid-grey window has to be asymmetric.** A tone curve crushes shadows, and a relative
  error in a small number is a large error in stops, so a reference below middle grey costs
  far more than one above. This is the same mechanism photographers already object to in
  phone meters, "the shadows are brought up and the highlights brought down", measured
  rather than argued.

The bench's own first draft was wrong in a way worth recording: it reported 0.87 stops of
tone-curve error at zero curve strength, where by construction there is no curve at all. Its
test scene was bright enough to clip, so it was measuring clipping. A bench that cannot be
trusted is worse than no bench, so the fix is noted in the file rather than quietly applied.

## What it cannot do, and why

- **Incident metering.** A handheld meter reads the light *falling on* the subject, through a
  white dome that gathers it from every direction at once. A phone camera has no dome, so it
  can only read light *reflected off* whatever it is pointed at. The two answers differ by
  however reflective the subject happens to be, which is exactly the thing an incident
  reading exists to stop mattering. Approximating one with the other would make the number
  look fine and be wrong, so the tool does not offer it.
- **Flash metering.** That needs the meter triggered in sync with the flash. A browser has no
  sync connection.
- **An absolute reading from the live preview on iOS.** Safari does not expose the camera's
  exposure time or ISO to the web, and without those there is no absolute reading to be had.
  Metering from a photograph works there instead, and needs no calibration at all, because a
  photograph carries its own exposure in its EXIF.
