### Install and Run Accuracy Benchmark Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/deepdive/Accuracy.md Navigate to the benchmark directory, install dependencies, and run the v1.7 accuracy test. ```bash cd bench/int16_poc npm install npm run accuracy:v1_7 ``` -------------------------------- ### Install and Run Benchmarks Source: https://github.com/glennwilton/jscolorengine/blob/main/bench/lcms-comparison/README.md Navigate to the comparison directory, install dependencies (which fetches lcms-wasm), and run the speed and accuracy comparison scripts. ```sh cd bench/lcms-comparison npm install # fetches lcms-wasm only node bench.js # speed comparison (~25s) node accuracy.js # accuracy comparison (~2s) ``` -------------------------------- ### Install Dependencies and Run Benchmark Source: https://github.com/glennwilton/jscolorengine/blob/main/bench/int16_poc/RESULTS.md Navigate to the benchmark directory, install npm packages, and execute the benchmark script. This fetches the lcms-wasm dependency and runs the comparison. ```bash cd bench/int16_poc npm install # fetches lcms-wasm node bench_int16_vs_lcmswasm.js ``` -------------------------------- ### Install MinGW-w64 Toolchain (MSYS2) Source: https://github.com/glennwilton/jscolorengine/blob/main/bench/lcms_c/README.md Install the necessary GCC and Make tools for native Windows builds using MSYS2. ```bash pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-make ``` -------------------------------- ### Build and Serve jscolorengine Benchmarks Source: https://github.com/glennwilton/jscolorengine/blob/main/README.md Commands to build the UMD bundle and serve the local benchmark application. Ensure Node.js is installed. ```bash npm run browser # build the UMD bundle (once) npm run serve # samples + browser bench on :8080 — see /samples/ and /samples/bench/ ``` -------------------------------- ### Build LCMS Benchmark (WSL2) Source: https://github.com/glennwilton/jscolorengine/blob/main/bench/lcms_c/README.md One-time installation of a C toolchain and building the benchmark on WSL2. Assumes lcms2 source has been fetched. ```bash # One-time: install a C toolchain sudo apt update sudo apt install -y build-essential # From the repo root, go into this folder (and fetch lcms2 once, # if you haven't already): cd bench/lcms_c ./fetch-lcms2.sh make # Run the bench: ./bench_lcms ``` -------------------------------- ### Start Local Static Server Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/Bench.md Starts a local static server using Node.js built-in http module. This is required to serve the benchmark files to the browser. You can specify a custom port using the --port flag. ```sh npm run serve ``` ```sh node samples/serve.js ``` ```sh node samples/bench/serve.js ``` ```sh node samples/serve.js --port=9000 ``` -------------------------------- ### LutBuilder Usage Example Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/deepdive/Luts.md Demonstrates the fluent chaining capabilities of the LutBuilder for creating a LUT transform. This example shows creating a LUT, setting its chain, adding metadata, and exporting it as a transform. ```APIDOC ## LutBuilder ### Description The `LutBuilder` is the primary API for creating and manipulating Look-Up Tables (LUTs). It offers a fluent interface allowing for method chaining to define the LUT's properties and output format. ### Methods - **`create(config, callback)`**: Initializes the LUT builder with configuration options and a callback function. `config` should include `inChannels`, `outChannels`, and `size`. The `callback` function processes the LUT data. - **`setChain(chain)`**: Sets the processing chain for the LUT. The `chain` argument typically includes input data, an intent, and an output definition. - **`addMeta(metadata)`**: Adds metadata to the LUT, such as author information. - **`toTransform(options)`**: Exports the configured LUT as a transform object. `options` can specify the `dataFormat`, e.g., 'int16'. - **`toJSON()`**: Serializes the LUT to a JSON representation. - **`toLut()`**: Exports the LUT in its raw format. - **`exportTIFF()`**: Exports the LUT as a TIFF file. ### Usage Example ```js const transform = new LutBuilder() .create({ inChannels: 3, outChannels: 4, size: 33 }, callback) .setChain([input, eIntent.perceptual, output]) .addMeta({ author: 'Glenn' }) .toTransform({ dataFormat: 'int16' }); ``` ### Error Handling Errors are thrown immediately with clear messages for invalid configurations or operations. Callers should use `try/catch` blocks for graceful error handling. ``` -------------------------------- ### Multi-Stage LUT Chain Example Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/deepdive/Luts.md This example demonstrates the structure of a multi-stage LUT chain, showing the sequence of color spaces, intents, and profile types that define a complex transformation. ```javascript lut.chain = [ { header: { colorSpace: 'RGB' }, name: 'sRGB', type: eProfileType.RGBMatrix, ... }, eIntent.perceptual, { header: { colorSpace: 'CMYK' }, name: 'GRACoL2006', type: eProfileType.CMYK, ... }, eIntent.relative, { header: { colorSpace: 'RGB' }, name: 'sRGB', type: eProfileType.RGBMatrix, ... }, ] ``` -------------------------------- ### Build and Serve Commands Source: https://github.com/glennwilton/jscolorengine/blob/main/samples/bench/README.md Commands to build the UMD bundle and start a local static server for the benchmark. Ensure the necessary files are vendored and profiles are present before running. ```sh npm run browser # build UMD bundle (once) npm run serve # samples/ + bench/ on :8080 (or: node samples/bench/serve.js for bench only) ``` -------------------------------- ### Serve In-Browser Benchmark UI Source: https://github.com/glennwilton/jscolorengine/blob/main/README.md Starts a local development server to run the in-browser comparison UI against lcms-wasm. Access it via localhost:8080. ```bash npm run serve ``` -------------------------------- ### Build and Serve jsColorEngine Source: https://github.com/glennwilton/jscolorengine/blob/main/samples/samples.html Commands to build the UMD bundle and start the development server for the jsColorEngine library. ```bash npm run browser # build the UMD bundle npm run serve # start dev server on :8080 (samples + bench) ``` -------------------------------- ### Build LCMS Benchmark (MinGW-w64) Source: https://github.com/glennwilton/jscolorengine/blob/main/bench/lcms_c/README.md Build the LCMS benchmark on native Windows using MinGW-w64 after installing the toolchain and fetching the source. ```bash ./fetch-lcms2.sh # or PowerShell: .\fetch-lcms2.ps1 mingw32-make ./bench_lcms.exe ``` -------------------------------- ### Start Live Video Softproofing Source: https://github.com/glennwilton/jscolorengine/blob/main/samples/live-video-softproof.html Initiates the live video softproofing process. This asynchronous function first builds the transformation, then plays the video, sets the running state, and starts the processing loop. It handles potential errors during the process. ```javascript async function start() { if (running) { stop(); return; } try { await buildTransform(); await video.play(); running = true; playBtn.innerHTML = '◼ Stop'; startLoop(); } catch (e) { console.error(e); statusText.textContent = 'Error: ' + e.message; } } ``` -------------------------------- ### Install jscolorengine with npm Source: https://github.com/glennwilton/jscolorengine/blob/main/README.md Install the jscolorengine package using npm. This is the primary method for adding the library to your project. ```bash npm i jscolorengine ``` -------------------------------- ### Build and Serve jsColorEngine Samples Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/Samples.md Commands to rebuild the browser UMD bundle and start a local development server for the samples and benchmarks. Ensure the necessary profiles and dist files are in place for specific demos. ```bash npm run browser # rebuild browser/jsColorEngineWeb.js npm run serve # start dev server on :8080 (samples + browser bench) ``` -------------------------------- ### Run JIT Inspection and Benchmarks Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/deepdive/JitInspection.md Execute commands to generate op-count tables, full assembly dumps, and throughput benchmarks. Ensure Node.js v20 or later is installed. ```bash node --allow-natives-syntax bench/jit_inspection.js ``` ```bash node --allow-natives-syntax --print-opt-code --code-comments \ bench/jit_asm_core_line.js 2>&1 > bench/jit_asm_core_dump.txt ``` ```bash pwsh bench/jit_asm_boundscheck.ps1 bench/jit_asm_core_dump.txt pwsh bench/jit_asm_spillcheck.ps1 bench/jit_asm_core_dump.txt ``` ```bash node bench/mpx_summary.js ``` -------------------------------- ### Node.js Color Conversion Example Source: https://github.com/glennwilton/jscolorengine/blob/main/README.md Demonstrates building a Lab to sRGB color conversion pipeline in Node.js and transforming a color. Requires importing necessary components from 'jscolorengine'. ```js const { Profile, Transform, eIntent, color } = require('jscolorengine'); (async () => { // ACCURACY PATH — single colour, full precision. // Build a Lab→sRGB pipeline once, then convert as many colours as you like. const lab2rgb = new Transform(); lab2rgb.create('*lab', '*sRGB', eIntent.relative); const rgb = lab2rgb.transform(color.Lab(70, 30, 30)); console.log(rgb); // { R: 233, G: 149, B: 118, type: 5 } })(); ``` -------------------------------- ### Get Pre-built LUT Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/Transform.md Retrieves the pre-built f64 CLUT including strides, gamut mode, chain, and Lab encoding metadata. Throws an error if no LUT is available. ```javascript transform.getLut() ``` -------------------------------- ### jsColorEngine Loader Usage Example Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/Loader.md Demonstrates how to use the Loader class to add, preload, and retrieve color profiles. It shows preloading profiles and lazy loading others, then using them for color transformations. ```javascript const { Loader, Transform, eIntent, color } = require('jscolorengine'); (async () => { const loader = new Loader(); loader.add('*lab', 'Lab', true); // preloaded loader.add('file:./profiles/sRGB_v4.icc', 'sRGB', true); // preloaded loader.add('file:./profiles/GRACoL2006.icc', 'CMYK', false); // lazy await loader.loadAll(); // 'Lab' and 'sRGB' are now ready const labProfile = await loader.get('Lab'); const cmykProfile = await loader.get('CMYK'); // loaded on demand here if (labProfile.loaded && cmykProfile.loaded) { const t = new Transform(); t.create(labProfile, cmykProfile, eIntent.perceptual); const lab = color.Lab(80.1, -22.3, 35.1); const cmyk = t.transform(lab); console.log(`CMYK: ${cmyk.C}, ${cmyk.M}, ${cmyk.Y}, ${cmyk.K}`); } })(); ``` -------------------------------- ### Content Fingerprint Example Source: https://github.com/glennwilton/jscolorengine/blob/main/samples/lutbuilder.md A content fingerprint is stamped into `lut.originalSignature`. This example shows the format. ```json "originalSignature": "FNV1A:26c2efad" ``` -------------------------------- ### Out-of-Gamut Clipping Example Discrepancies Source: https://github.com/glennwilton/jscolorengine/blob/main/bench/lcms-comparison/README.md Specific examples of input CMYK values that result in out-of-gamut colors, showing the differing R channel outputs between jsColorEngine and lcms. ```text in (192, 0, 64, 32) js ( 0,163,174) lcms (14,163,174) Δmax=14 in (192, 0, 64, 0) js ( 0,181,193) lcms (13,181,193) Δmax=13 in (224, 64,224, 0) js ( 1,139, 84) lcms (11,139, 84) Δmax=10 in (192, 0, 32, 64) js ( 0,146,172) lcms ( 9,146,172) Δmax= 9 ``` -------------------------------- ### Start Video Processing Loop Source: https://github.com/glennwilton/jscolorengine/blob/main/samples/live-video-softproof.html Initializes and starts the video processing loop. It checks for the `lockFpsCb` setting and `hasVFC` availability to decide whether to use `requestVideoFrameCallback` or `requestAnimationFrame`. ```javascript function startLoop() { lastFpsUpdate = performance.now(); frameCount = 0; transformMsAccum = 0; if (lockFpsCb.checked && hasVFC) { vfcId = video.requestVideoFrameCallback(vfcLoop); } else { rafId = requestAnimationFrame(rafLoop); } } ``` -------------------------------- ### LutBuilder Workflow Overview Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/deepdive/Luts.md This diagram illustrates the typical workflow for using the LutBuilder, from entry points to outputting the final LUT. ```text ┌──────────────────────────────────────────────────────────────┐ │ Entry points │ │ │ │ new LutBuilder() — empty, then .create() │ │ new LutBuilder(lut) — from getLut() object │ │ LutBuilder.fromJSON(json) — from serialised file │ │ LutBuilder.fromTransform(t) — from existing Transform │ └──────────────────────┬───────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────┐ │ Build / Load │ │ │ │ .create(opts, callback) — synthetic (u16 canonical) │ │ .createIdentity(ch, size) — blank canvas for TIFF │ │ .createFromLCMS(lcms, ...) — lcms-wasm bridge │ │ .importTIFF(buffer) — from edited TIFF (Stage 3) │ └──────────────────────┬───────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────┐ │ Mutate / Annotate │ │ │ │ .editLut(callback) — programmatic per-cell edits │ │ .clone() — deep copy for variants │ │ .addMeta({...}) — merge metadata │ │ .addCopyright(str) — set copyright │ │ .addAdjustment(str) — append to edit history │ │ .setChain([...]) — set/override profile chain │ └──────────────────────┬───────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────┐ │ Output │ │ │ │ .toTransform(opts) — ready-to-use Transform │ │ .toJSON(opts) — portable JSON (§5 format) │ │ .toLut() — raw LUT object │ │ .exportTIFF(opts) — TIFF for visual editing │ │ .analyze(src, expected) — accuracy report │ └──────────────────────┴───────────────────────────────────────┘ All methods except output return `this` — fluent chaining throughout. Errors throw immediately with clear messages. ``` -------------------------------- ### Live video soft-proof demo configuration Source: https://github.com/glennwilton/jscolorengine/blob/main/CHANGELOG.md The live video soft-proof demo's createMultiStage chain already ended with eIntent.relative before sRGB. This configuration is now documented as the reference pattern alongside other demos. ```html samples/live-video-softproof.html — `createMultiStage` chain already ended with `eIntent.relative` before sRGB; unchanged, now documented as the reference pattern alongside the other demos. ``` -------------------------------- ### LutBuilder Entry Points Source: https://github.com/glennwilton/jscolorengine/blob/main/CHANGELOG.md Demonstrates various ways to instantiate the LutBuilder, including from scratch, from a transform, or from JSON data. ```javascript new LutBuilder() LutBuilder.fromTransform(t) LutBuilder.fromJSON(json) ``` -------------------------------- ### Serialized LUT Data Example Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/Roadmap.md An example of how a serialized LUT would appear, including the `inLab` and `outLab` encoding data. This self-describing block allows immediate identification of the profile encoding used without complex back-solving. ```json "inLab": { "pcsVersion": 4, "labNumerator": 65535, "abDenominator": 255 }, "outLab": { "pcsVersion": 2, "labNumerator": 65280, "abDenominator": 256 } ``` -------------------------------- ### Get Original LUT Signature Source: https://github.com/glennwilton/jscolorengine/blob/main/samples/lutbuilder.md Retrieve the original, read-only signature of the LUT. ```javascript .originalSignature ``` -------------------------------- ### Get Current LUT Signature Source: https://github.com/glennwilton/jscolorengine/blob/main/samples/lutbuilder.md Compute and retrieve the signature of the current LUT data on demand. ```javascript .signature() ``` -------------------------------- ### Creating Virtual and Loading ICC Profiles Source: https://github.com/glennwilton/jscolorengine/blob/main/README.md Demonstrates the creation of a virtual profile and the loading of an ICC profile from disk. Prefer virtual profiles for common RGB spaces to avoid I/O and decode time. ```javascript // These two profiles are functionally identical. // Prefer the virtual one — same maths, no I/O, no decode time. const fast = new Profile('*sRGB'); // ~0 ms // If you must load from disk, always wrap + check: const slow = new Profile(); try { await slow.loadPromise('./profiles/sRGB_v4_ICC_preference.icc'); } catch (err) { console.error('Profile load failed:', err.message); } if (!slow.loaded) { console.error('Profile invalid:', slow.lastError); } ``` -------------------------------- ### Get WASM Memory Bytes Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/Transform.md Returns the total bytes currently held across all WASM states for diagnostic purposes. ```javascript transform.wasmMemoryBytes() ``` -------------------------------- ### LutBuilder Entry Points Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/deepdive/Luts.md Demonstrates how to instantiate the LutBuilder class, either empty, from an existing LUT object, from JSON, or from an existing Transform. ```APIDOC ## LutBuilder Entry Points ### Description Instantiate the `LutBuilder` class. It can be initialized empty, with an existing LUT object, from a JSON string or object, or from an existing Transform. ### Methods - `new LutBuilder()` - `new LutBuilder(lut: object) - `LutBuilder.fromJSON(jsonStringOrObject: string | object) - `LutBuilder.fromTransform(existingTransform: object) ### Usage Examples ```js // Empty — then call a create method const builder = new LutBuilder(); // From an existing LUT object (e.g. from transform.getLut()) const builder = new LutBuilder(lut); // From serialised JSON (reverses .toJSON()) // Accepts a JSON string OR an already-parsed object: const builder = LutBuilder.fromJSON(jsonString); const builder = LutBuilder.fromJSON(parsedObject); // From an existing Transform const builder = LutBuilder.fromTransform(existingTransform); ``` ``` -------------------------------- ### Compile Pipeline with Bit-Exact Math.pow Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/deepdive/CompiledPipeline.md Example of how to disable gamma LUT optimization for bit-exact floating-point calculations when needed for measurement or verification. ```javascript t.compile({ useGammaLUT: false }); // bit-exact f64, no LUT ``` -------------------------------- ### Build and Consume Portable LUTs Source: https://github.com/glennwilton/jscolorengine/blob/main/README.md Demonstrates how to create a LUT at build time using color profiles and then load and use it at runtime without needing the original profiles. The `dataFormat` option specifies the data format for the LUT. ```javascript // Producer (build time — has profiles) const t = new Transform({ dataFormat: 'int8', buildLut: true }); t.create(cmykProfile, '*srgb', eIntent.relative); fs.writeFileSync('lut.json', JSON.stringify(t)); // Consumer (runtime — profiles not needed) const t = Transform.fromJSON(fs.readFileSync('lut.json'), { dataFormat: 'int8' }); t.transformArray(cmykPixels); ``` -------------------------------- ### Creating Virtual Profiles with LutBuilder Source: https://github.com/glennwilton/jscolorengine/blob/main/samples/lutbuilder.md Demonstrates how to create minimal or fully-populated virtual profiles for use with setLut(). Supports various color spaces and provides shorthand options. ```javascript const { virtualProfile, virtualRGB, virtualCMYK, virtualGray, virtualLab } = require('./LutBuilder'); // Minimal — header.colorSpace, name, type, version (all that setLut() needs) virtualRGB('My RGB output'); virtualCMYK('GRACoL press'); virtualGray('Mono'); virtualLab('Lab working'); // Fully-populated — '*' prefix delegates to the engine's built-in virtuals, // adding whitepoint, PCS encoding, primaries, etc. virtualRGB('*sRGB'); // sRGB IEC61966-2.1 virtualRGB('*AdobeRGB'); // AdobeRGB 1998 virtualRGB('*ProPhotoRGB'); // ProPhoto RGB virtualLab('*Lab'); // Lab D50 virtualLab('*LabD65'); // Lab D65 (the only D65 default) // String shorthand — these are equivalent: virtualProfile('*sRGB'); virtualProfile({ name: '*sRGB' }); virtualRGB('*sRGB'); ``` -------------------------------- ### Get Transform Chain Information Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/Transform.md The `transform.chainInfo()` method returns a formatted dump detailing how the transform's processing pipeline was constructed. ```javascript transform.chainInfo() ``` -------------------------------- ### Initialize Build Process on User Interaction Source: https://github.com/glennwilton/jscolorengine/blob/main/samples/softproof-vs-lcms.html Sets up event listeners for UI controls like buttons and select elements to trigger a 'build' function. This allows users to re-render or update the color comparison based on selected profiles, intents, or images. ```javascript runBtn.addEventListener('click', build); profileSel.addEventListener('change', build); intentSel.addEventListener('change', build); imageSel.addEventListener('change', build); build(); ``` -------------------------------- ### Get Transform Stage Names Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/Transform.md The `transform.getStageNames()` method returns an array of strings, where each string is the name of a stage within the built processing pipeline. ```javascript transform.getStageNames() ``` -------------------------------- ### Sample Input/Output in sRGB to Lab Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/deepdive/Accuracy.md This sample demonstrates the input RGB values and their corresponding Lab output, showing a very small residual in the 'a' and 'b' channels. This precision is critical for understanding the accuracy of floating-point transformations. ```text INPUT(0,0,0) → OUTPUT(L=0.0, a=7.57e-6, b=7.57e-6) ``` -------------------------------- ### Importing jscolorengine with Bundlers Source: https://github.com/glennwilton/jscolorengine/blob/main/README.md Example of importing components from jscolorengine for use with modern JavaScript bundlers like Webpack or Vite. This import statement is standard for tree-shaking. ```js import { Profile, Transform, eIntent, color } from 'jscolorengine'; ``` -------------------------------- ### Create LUT with LutBuilder Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/Roadmap.md Use `LutBuilder.create(callback)` to start building a LUT. The callback function is invoked with the builder instance to define the LUT's content. ```javascript LutBuilder.create(callback) ``` -------------------------------- ### Method: img.toProof Source: https://github.com/glennwilton/jscolorengine/blob/main/samples/ICCImage.md Performs a soft-proof conversion: src → proofProfile → *sRGB. The returned image is sRGB-tagged. ```APIDOC ## img.toProof(proofProfile, { intent, BPC } = {}) ### Description Performs a soft-proof conversion: src → proofProfile → *sRGB. The returned image is sRGB-tagged. ### Method `await img.toProof(proofProfile, options)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **proofProfile** (`Profile` or `string`) - Required - The profile to proof against. * **intent** (`Intent` or `Array`) - Optional - The rendering intent(s). * **BPC** (`boolean` or `Array`) - Optional - Black point compensation setting(s). ``` -------------------------------- ### Transform Class Initialization and Pipeline Creation Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/deepdive/Architecture.md Instantiate the Transform class with source and destination profiles, an intent, and optional custom stages. Then, use the create method to build the optimized color conversion pipeline. ```javascript new Transform({...}).create(src, dst, intent) ``` -------------------------------- ### DOM Element References Source: https://github.com/glennwilton/jscolorengine/blob/main/samples/softproof.html Gets references to various HTML elements used for user interaction and displaying information. These elements must exist in the HTML document. ```javascript const imgEl = document.createElement('img'); imgEl.crossOrigin = 'anonymous'; const runBtn = document.getElementById('runBtn'); const profileSel = document.getElementById('profileSelect'); const intentSel = document.getElementById('intentSelect'); const imageSel = document.getElementById('imageSelect'); const gamutSel = document.getElementById('gamutSelect'); const screenCv = document.getElementById('screenCanvas'); const proofCv = document.getElementById('proofCanvas'); const screenInfo = document.getElementById('screenInfo'); const proofInfo = document.getElementById('proofInfo'); const channelHost = document.getElementById('channelContainer'); const timingInline = document.getElementById('timingInline'); const tooltip = document.getElementById('pickerTooltip'); const tipSwatchRGB = document.getElementById('tipSwatchRGB'); const tipSwatchCMYK = document.getElementById('tipSwatchCMYK'); const tipBody = document.getElementById('tipBody'); ``` -------------------------------- ### Convenience Wrappers for Common Color Spaces Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/deepdive/Luts.md Utilize convenience wrappers like `virtualRGB`, `virtualCMYK`, `virtualGray`, and `virtualLab` for quick creation of virtual profiles for standard color spaces. These wrappers simplify the process by pre-configuring common settings. ```javascript virtualRGB('sRGB-like input') // → { header: {colorSpace:'RGB'}, type: eProfileType.RGBMatrix, ... } virtualCMYK('GRACoL press') // → { header: {colorSpace:'CMYK'}, type: eProfileType.CMYK, ... } virtualGray('Mono output') // → { header: {colorSpace:'GRAY'}, type: eProfileType.Gray, ... } virtualLab('Lab working space') // → { header: {colorSpace:'Lab'}, type: eProfileType.Lab, version: 4, ... } ``` -------------------------------- ### Get Transform Optimiser Information Source: https://github.com/glennwilton/jscolorengine/blob/main/docs/Transform.md The `transform.optimiseInfo()` method returns a formatted dump detailing the optimizations applied by the pipeline's optimiser, showing what transformations were collapsed. ```javascript transform.optimiseInfo() ```