Editor › color-accuracy
How does PhotoAIA manage colour, and how accurate is it?
PhotoAIA reads the ICC profile embedded in your file, uses it to interpret the pixel numbers, and converts them to the canvas colour space with LittleCMS compiled to WebAssembly — the same colour engine used across the industry — running entirely on your machine. That conversion is measured against exact LittleCMS at ΔE2000 ≤ 1.0, below the threshold at which a difference is normally noticeable side by side.
Why a browser editor needs to do this itself
A canvas element is an sRGB surface. Hand it the raw numbers from an Adobe RGB or Display P3 file and the browser interprets them as sRGB — the classic "my wide-gamut file looks flat" problem. A colour-managed application must therefore convert from the document's space into the canvas's space itself.
Browsers cannot be relied on to do this for you. Every major engine implements only the matrix/TRC part of the ICC specification: Firefox's colour engine explicitly does not support display cLUTs, and Chrome's falls back to the matrix component when a look-up table is present. Most CMYK profiles and many camera and scanner profiles are LUT-based — precisely the profiles print work depends on. So PhotoAIA carries a full CMM (LittleCMS) and does the transforms itself.
The pipeline, stage by stage
- Import — the embedded profile is read byte-exact (TIFF tag 34675, PSD resource 1039, JPEG APP2, PNG iCCP) and validated from its header before the colour engine sees it.
- Assign — a valid RGB profile tags the document. Assigning changes what the numbers MEAN; it never alters a pixel, and it is undoable.
- Display transform — document space to sRGB through LittleCMS, baked into a 33-node 3D lookup table that the CPU and GPU renderers sample. The grid size was chosen by measurement, not habit: a coarser grid measured ΔE2000 1.83 near white, above the noticeable threshold.
- Soft proof — when enabled, the printing condition is folded into that same transform (document → press → sRGB) so pixels make one trip through the colour engine rather than two.
- Export — a file is tagged only with the profile its pixels are actually in. Never with a preference.
Rendering intents and black point compensation
All four ICC rendering intents are available, and PhotoAIA does not implement its own gamut mapping — it asks LittleCMS, so the perceptual behaviour comes from the destination profile's own table, as the specification intends. Black point compensation is available and behaves correctly: measurement confirms it changes shadows substantially while leaving highlights essentially untouched, which is what distinguishes real BPC from a naive shadow lift.
What has been measured
| Capability | Status | How it was established |
|---|---|---|
| Adobe RGB display | Verified | ΔE2000 ≤ 1.0 vs exact LittleCMS; measured in the test suite |
| Display P3 display | Verified | same measurement |
| sRGB (no spurious conversion) | Verified | near-identity measured ≤ ΔE2000 1.0 |
| ICC profile detection | Verified | TIFF, PSD, JPEG, PNG; byte-exact round-trip tests |
| Rendering intents differ correctly | Verified | measured ≥ ΔE2000 2 between intents through a real GRACoL profile |
| Black point compensation | Verified | shadows ≥ ΔE2000 2, highlights ≤ 1.5 |
| Soft proof | Verified | proof vs no proof ≥ ΔE2000 2 |
| TIFF / PSD profile preservation | Verified | byte-exact import and export tests |
| Export tagging honesty | Verified | a file is tagged only with the profile its pixels are in |
| CMYK separation | Verified | profile-driven, validated against a locked reference |
| CMYK on-screen composite | Limited | uses a device approximation, not the profile — soft-proof the RGB master for accuracy |
| Screen-to-monitor match | Not possible in a browser | no browser exposes the display profile to a web page |
What PhotoAIA does not claim
- It cannot match your monitor's profile — no browser gives a web page access to it. That last step belongs to your operating system.
- It is not a substitute for a contract proof. A soft proof is a working tool.
- Editing is 8 bits per channel. A 16-bit file passes through losslessly only while you crop, rotate or flip it.
- No comparison against Photoshop is claimed: that measurement was not performed, and inventing numbers for it would be worse than leaving it undone.
- The GPU (WebGL2) renderer is verified to sample the same measured lookup table as the CPU path, by checking its addressing arithmetic — it is not independently measured by rendering pixels. An earlier version of that shader was wrong in a way the CPU measurements could not see, which is why the distinction is stated rather than glossed.
Questions
- Is my file uploaded for colour conversion?
- No. The colour engine runs in your browser as WebAssembly. Files and profiles stay on your machine.
- Which colour engine is used?
- LittleCMS, compiled to WebAssembly — a widely used open-source CMM, not a home-made approximation.
- Why does my image look different in another application?
- Usually because that application interprets the file differently, or your display profile differs from what the other application assumes. The plain check is whether the file carries a profile and whether both applications honour it.
- Can I trust the soft proof for press sign-off?
- Treat it as a working preview. It is profile-accurate, but your display and its calibration are outside any browser application's control.