Skip to content

Unify colormaps: render-time apply (pseudocolor) + pipeline-based decode#9

Merged
kleinicke merged 2 commits into
mainfrom
dev/colormap
Jun 17, 2026
Merged

Unify colormaps: render-time apply (pseudocolor) + pipeline-based decode#9
kleinicke merged 2 commits into
mainfrom
dev/colormap

Conversation

@kleinicke

@kleinicke kleinicke commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Summary

Reworks colormaps into one unified, non-destructive feature with two directions, both flowing through the central ImageRenderer pipeline (so they work for every format and for layers).

Issues with the colormaps were reported in #2

  • Shared module media/modules/colormaps.jsgetColormapLut() (cached 256-entry RGB LUT) and rgbToColormapIndex() (cached 32³ inverse cube → O(N) decode).
  • Apply (add color) — new displayColormap render setting, hooked once in ImageRenderer.render(): single-channel grayscale is remapped through the LUT (NaN preserved). Reversible, non-destructive, works in layers.
  • Decode (remove color) — replaces the broken canvas-mutating converter; decoded scalar becomes a first-class single-channel float source rendered through the pipeline, feeding the pixel inspector.
  • UX — context menu splits into Apply/Remove Colormap (single-channel) and Decode Colormap to Float (RGB); new tiffVisualizer.applyColormap command; displayColormap persists across tab switches.
  • Fixes — revert now re-posts the original formatInfo (full menu/status bars restored); gamma-mode normalization labels are type-aware (0-1 float, 0-255/0-65535 integer).

Testing

  • JS/TS bundles build and lint clean.
  • Colormap apply→decode round-trip verified accurate to ≤1 inverse-cube cell across all 9 colormaps.

kleinicke and others added 2 commits June 17, 2026 11:19
Rework the colormap feature into one unified, non-destructive design with
two directions, both flowing through the central ImageRenderer pipeline so
they work for every format and for layers.

- Add shared media/modules/colormaps.js as the single source of truth:
  getColormapLut() (cached 256-entry RGB LUT) and rgbToColormapIndex()
  (cached 32^3 inverse cube for O(N) decode).

- Apply ("add color"): new displayColormap render setting, hooked once in
  ImageRenderer.render() — single-channel grayscale output is remapped
  through the colormap LUT (NaN pixels preserved). Reversible and
  non-destructive; works in layers since the compositor uses the same path.

- Decode ("remove color"): rewrite the broken canvas-mutating converter.
  The decoded scalar becomes a first-class single-channel float source that
  re-renders through ImageRenderer (so normalization/gamma/apply-colormap all
  work) and feeds the pixel inspector via a new decodedValueProvider.

- UX: context menu splits into "Apply Colormap…"/"Remove Colormap" for
  single-channel images (fixes the missing option on float TIFFs) and
  "Decode Colormap to Float" for RGB images; add tiffVisualizer.applyColormap
  command; persist displayColormap across tab switches.

- Guard the PNG lazy-native fast path so a requested colormap forces the
  central pipeline.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kleinicke kleinicke merged commit 4c6e073 into main Jun 17, 2026
1 check passed
kleinicke added a commit that referenced this pull request Jun 17, 2026
Unify colormaps: render-time apply (pseudocolor) + pipeline-based decode
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant