Add IccProfilePlot: data-first profile visualization API + CLI#1264
Add IccProfilePlot: data-first profile visualization API + CLI#1264colourbill-ctrl wants to merge 3 commits into
Conversation
Introduces a standalone Tools/CmdLine tool, iccProfilePlot, built on a new data-first visualization model (IccVizModel). Where iccProfileVisualize renders a finished PDF/TIFF report, IccVizModel returns the underlying DATA for each visualization — point series + axis hints for graphs, ICC-normalized samples + geometry for the nD CLUT raster — so a caller can draw, colour-manage, or expose individual graphs however it likes. The visualization math, structure, comments and granular stderr diagnostics are carried over from iccProfileVisualize as faithfully as possible, so the two read alike; the tool depends only on IccProfLib. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Note that MiniPDF and MiniTIFF don't call libraries: they are self-contained, so profileVisualize also has no additional dependencies. |
|
OK, code looks decent. |
|
if you're ok with it, I'll start work on pulling in the rest of the functionality (minitiff, etc) up to putting together something with the same calling approach as the current iccProfileVisualize and emitting PDF. |
Add a PDF/TIFF report generator that drives off IccVizModel instead of
walking the profile inline: processLuts() enumerates via iccviz and draws
each graph/raster with the dependency-free Mini{PDF,SVG,TIFF} writers.
Reproduces the standalone iccProfileVisualize artifacts byte-for-byte over
a 90-profile corpus (355/355 per-tag TIFFs, 77/77 PDFs identical).
IccVizModel gains Enumerate(pIcc, Order) -- Order::TagTable reorders to the
profile's tag-table page sequence (Order::Canonical stays the portable
default) -- and v5 named colours (icSigTagArrayType: NamedColorArray /
ColorantInfoArray) in collectNamedColors, with the PCS basis aligned to the
profile header PCS.
Registers an iccProfileVisualizePlot CMake target.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rewrite The processLuts rewrite (data-first dispatch) dropped several future-work breadcrumbs carried over from iccProfileVisualize, including the gamut-plot TODO tied to the in-flight convex_hull2D work. Restore them (comment-only): gamut-from-A2B/B2A (annotated to the reserved convex_hull2D/cross helpers), named-spectra, response curves, curveSetElement/singleSampledCurve/ segmentedCurve, and the spectra->PCS note in the v5 named-colour branch. No code change; convex_hull2D, cross(), and outputResponseCurves were already intact (the earlier prune removed only the superseded extraction layer). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Request for Review2026-06-14 01:55:09 UTC @maxderhak When time permits this PR #1264 is Pending your Approval to Merge. Thank You |
xsscx
left a comment
There was a problem hiding this comment.
Code Review
2026-06-18 16:27:52 UTC
Please review suggested corrections & minimization changes on Branch https://github.com/InternationalColorConsortium/iccDEV/tree/ci-refactor-cmake-pr1264
PR Dupe Files
- MiniPDF.cpp
- MiniPDF.hpp
- MiniSVG.cpp
- MiniSVG.hpp
- MiniTIFF.cpp
- MiniTIFF.hpp
- spectralLocus.hpp
Remarks
- byte-identical
Harvest Branch
- PR net minus dupes
xsscx
left a comment
There was a problem hiding this comment.
PR Status
2026-06-18 17:09:06 UTC
- PR opened Date: Sun Jun 7 22:27:40 2026 -0700
- PR Review Window 14 days on Sun Jun 21 22:27:40 2026 -0700
Observations
- Maintainer Authored - @colourbill-ctrl
- Maintainer Approved - @ChrisCoxArt
- Valid Use Cases
- Code Reuse
- iccProfileVisualizer
- Output Writers
- Manual Code Review - @xsscx
- Automated Code Review
- Cleared all CI PR Checks
Resolution
- Label of Merge Pending will be Added
- Intent to Merge 30-June-2026 pending:
- Merge Approvals Withdrawn
- Requested Changes by ICC Leads
What this is
A new, standalone command-line tool —
iccProfilePlot— underTools/CmdLine/IccProfilePlot/, built on a new data-first visualization model,IccVizModel. WhereiccProfileVisualizerenders a finished PDF/TIFF report,IccVizModelreturns the underlying data for each visualization:A caller then draws, colour-manages, or exposes individual graphs and their data however it likes — into a PDF, an SVG, JSON, or an interactive UI.
Developed in parallel to
iccProfileVisualize, on purposeThis is effectively a major refactor of the
iccProfileVisualizevisualization code toward a data-first API. For regression and safety, that refactor is being carried out outside theiccProfileVisualizecodebase rather than in place —iccProfileVisualizeis left completely untouched, so there is no risk to the actively-developed tool, and the two can be diffed and validated independently. The intent is a parallel track that can later converge, not an in-place rewrite.Faithful to the original where it counts
As much as possible, the original guard rails, commenting, and structure have been preserved, so the two read alike:
Skipping <tag>: invalid CLUT width,WARNING - tile count overflow., …).A silent mode lets the caller turn the CLI/stderr diagnostic echo on or off to suit its context: by default the model echoes diagnostics to stderr exactly like
iccProfileVisualize(so the CLI behaves identically out of the box); a library embedding (e.g. WASM/browser) callsSetSilent(true)to suppress it, while still receiving every reason as structured data. A per-callVerbositycan override the global switch either way.The API
See the usage guide at the top of
IccVizModel.hpp, echoed as a worked example iniccProfilePlot.cpp:Pick a visualization by
Kind, supply aCIccProfile*, and render the one you want as graph data or raster samples.Scope note: the demo tool does not emit PDF (yet)
iccProfilePlotis a demonstration consumer of the API — it lists visualizations and serializes the returned graph/raster data (JSON / raw samples). It deliberately does not emit a PDF at this point; producing a finished report would require drawing the returned data into MiniPDF (the rendering layericcProfileVisualizeuses), which is intentionally left out so the model and this tool stay dependency-light (IccProfLibonly). The commented walkthrough iniccProfilePlot.cppshows exactly where a PDF generator would slot in.Build / test
Build/Cmake/Tools/IccProfilePlot/CMakeLists.txt, registered in the top-level CMake; builds clean againstIccProfLibvia the standard CMake build.iccProfilePlot <profile> list | graph <id> | raster <id> [out.raw].🤖 Generated with Claude Code
Update — second commit (
bbd8109): a PDF/TIFF report tool on the engineThe scope note above ("the demo tool does not emit PDF yet") is now addressed: a
second tool draws finished artifacts through the engine.
iccProfileVisualize(in the sameTools/CmdLine/IccProfilePlot/dir — a parallel,data-first reimplementation; the standalone tool of the same name is left untouched)
reproduces that tool's PDF (tone curves, chromaticity, named-colour scatters) and
per-tag TIFF output. Instead of walking the profile and computing geometry inline,
it enumerates and renders through
IccVizModeland draws the returned data withthe dependency-free Mini{PDF,SVG,TIFF} writers. The engine is the single source of
the maths; the tool is just a drawing front-end.
Changes (all under
Tools/CmdLine/IccProfilePlot/, plus the tool's CMake target)iccProfileVisualize.cpp—processLuts()callsiccviz::Enumerate(),then per descriptor
RenderGraph/RenderRaster, drawing each with the Miniwriters (
renderChromaticityGraph,renderCurveGraph, the reusedgraphNamedColorsPDF, andWriteTIFFstraight from the raster). The originaldrawing primitives and reference-geometry XObjects are preserved verbatim; the
now-superseded inline extractors were removed (lineage noted in comments).
MiniPDF/MiniSVG/MiniTIFF— the dependency-free writers carriedover from the standalone tool. No third-party libraries.
IccVizModel.{hpp,cpp}—Enumerate(pIcc, Order order = Order::Canonical):Canonicalis the existing fixed, cross-module/WASM-safe order; the opt-inOrder::TagTablereorders the same descriptors to the profile's tag-table pagesequence so a report matches the original. Also v5 named colours in
collectNamedColors(icSigTagArrayType: NamedColorArray / ColorantInfoArray —PCS float arrays → Lab, names via UTF8/UTF16/Text/MLU, tint-% suffixes), with the
PCS basis aligned to the profile header PCS.
Build/Cmake/Tools/IccProfilePlot/CMakeLists.txt— registers aniccProfileVisualizePlotexecutable (distinct output name so it doesn't clashwith the standalone
iccProfileVisualizeon install). Verified to configure andbuild in-tree.
Testing
Built both tools against the same
IccProfLiband ran them over a 90-profile corpus(RGB matrix, CMYK / N-colour CLUT, named/spot, wide-gamut, iccMAX), comparing every
artifact byte-for-byte against the original standalone
iccProfileVisualize:Order::TagTable)IccVizModel.cppcompiles clean under-Wall -Wextra. One intentional difference: apresent-but-malformed curve (e.g.
bad-bluecurve.icc) is enumerated and rendered witha diagnostic, where the original silently dropped the page — consistent with IccViz's
"surface the reason" design.