Skip to content

Add probe mode to efficiently detect UltraHDR images - #6

Merged
adamsilverstein merged 3 commits into
mainfrom
5-add-probe-mode
Jan 30, 2026
Merged

adamsilverstein merged 3 commits into
mainfrom
5-add-probe-mode

Conversation

@adamsilverstein

@adamsilverstein adamsilverstein commented Jan 30, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Adds probeUltraHdr() function that efficiently validates if an image is UltraHDR by checking for required components (primary image, gain map, metadata) without full decoding
  • Returns structured UltraHdrProbeResult with detailed information useful for batch processing and filtering
  • Never throws - always returns a result object, even for invalid inputs

Features

The probe result includes:

  • isValid - Whether image has all required UltraHDR components
  • hasPrimaryImage - Whether a valid JPEG was found
  • hasGainMap - Whether a gain map image was found
  • hasMetadata - Whether XMP gain map metadata was found
  • width, height - Primary image dimensions (0 if not found)
  • gainMapWidth, gainMapHeight - Gain map dimensions (0 if not found)
  • hdrCapacity - HDR capacity in stops (0 if not found)
  • metadataVersion - Metadata version string (empty if not found)

Example Usage

const result = await probeUltraHdr(buffer);

if (result.isValid) {
    console.log('UltraHDR image:', result.width, 'x', result.height);
    console.log('HDR capacity:', result.hdrCapacity, 'stops');
} else {
    // Diagnose why it's not valid
    if (!result.hasPrimaryImage) console.log('Not a valid JPEG');
    if (!result.hasGainMap) console.log('Missing gain map');
    if (!result.hasMetadata) console.log('Missing HDR metadata');
}

Test plan

  • Rust tests pass (48 tests including 4 new probe tests)
  • JS tests pass (47 tests including 11 new probe tests)
  • Test cases cover: empty buffer, PNG, regular JPEG, structured result diagnostics, dimensions extraction, never throws

Closes #5

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added probeUltraHdr() to inspect UltraHDR images and return structured diagnostics: validity, component presence, primary/gain-map dimensions, HDR capacity, and metadata version — without full decoding.
  • Tests

    • Added comprehensive tests for valid/invalid inputs, edge cases, truncated/random data, metadata/gain-map absence, and non-crashing behavior to ensure robust probing.

✏️ Tip: You can customize this high-level summary in your review settings.

Implements a new probe() function that efficiently validates if an image
is UltraHDR by checking for required components (primary image, gain map,
metadata) without full decoding. Returns structured results useful for
batch processing and filtering.

Features:
- Never throws - always returns an UltraHdrProbeResult
- Checks JPEG magic bytes first for early return on non-JPEGs
- Provides detailed flags: isValid, hasPrimaryImage, hasGainMap, hasMetadata
- Extracts dimensions, HDR capacity, and metadata version when available
- Reuses existing parsing infrastructure (no image decompression)

Files changed:
- wasm/src/types.rs: Add UltraHdrProbeResult struct
- wasm/src/ultrahdr/decoder.rs: Add probe() function + tests
- wasm/src/ultrahdr/mod.rs: Export probe
- wasm/src/lib.rs: Add WASM binding probeUltraHdr
- js/src/types.ts: Add TypeScript interface
- js/src/index.ts: Add async wrapper and exports
- js/__tests__/probe.test.ts: Add 11 test cases

Closes #5

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jan 30, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds a probe mode that inspects image buffers for UltraHDR components without full decoding, exposing a new JS API probeUltraHdr and corresponding WASM/Rust probe_ultra_hdr returning a structured UltraHdrProbeResult.

Changes

Cohort / File(s) Summary
Type Definitions
js/src/types.ts, wasm/src/types.rs
Introduce UltraHdrProbeResult (JS interface + Rust struct) with validity flags, component presence, dimensions, hdrCapacity, and metadataVersion; includes wasm_bindgen bindings and sensible defaults.
JavaScript API & Tests
js/src/index.ts, js/__tests__/probe.test.ts
Export new probeUltraHdr(buffer: ArrayBuffer): Promise<UltraHdrProbeResult> that delegates to WASM; add comprehensive tests validating behavior on empty, non-JPEG, truncated, random, and valid JPEG inputs.
WASM Core Implementation
wasm/src/lib.rs, wasm/src/ultrahdr/decoder.rs, wasm/src/ultrahdr/mod.rs
Add WASM-exported probe_ultra_hdr and probe decoder function that parses JPEG structure, extracts dimensions, detects XMP/MPF gain map or secondary JPEG, sets composite validity flags, and re-exports the probe symbol. Tests added for edge cases.

Sequence Diagram

sequenceDiagram
    participant Client
    participant JS_API as JS API
    participant WASM as WASM Module
    participant Decoder as Decoder

    Client->>JS_API: probeUltraHdr(buffer: ArrayBuffer)
    JS_API->>WASM: call probeUltraHdr(buffer: Uint8Array)
    WASM->>Decoder: probe(data: &[u8])
    Decoder->>Decoder: quick JPEG validation & parse segments
    Decoder->>Decoder: extract primary image dimensions
    Decoder->>Decoder: detect XMP metadata
    Decoder->>Decoder: probe for gain map (MPF or second JPEG)
    Decoder-->>WASM: UltraHdrProbeResult
    WASM-->>JS_API: UltraHdrProbeResult
    JS_API-->>Client: resolve Promise<UltraHdrProbeResult>
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I sniff the bytes with nimble paws,
I count the dims and check the laws,
Gain maps hide or metadata sings,
I hop through headers, flit my wings,
UltraHDR found — carrot-bright applause!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a probe mode for efficient UltraHDR detection without full decoding.
Linked Issues check ✅ Passed The PR implements all objectives from issue #5: probe function for UltraHDR detection, component presence detection, diagnostic information exposure, and safe batch processing API.
Out of Scope Changes check ✅ Passed All changes directly support the probe mode feature: new types, WASM implementation, JS bindings, and comprehensive tests with no unrelated modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 5-add-probe-mode

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@js/__tests__/probe.test.ts`:
- Around line 1-145: Prettier formatting errors in the test file are causing CI
failures; run Prettier on this file (or the whole repo) to apply the project's
formatting rules and commit the changes. Specifically, format
js/__tests__/probe.test.ts (which contains tests referencing probeUltraHdr,
base64ToArrayBuffer, REGULAR_JPEG_BASE64, PNG_HEADER_BASE64) using your
project's Prettier config (e.g., npx prettier --write js/__tests__/probe.test.ts
or yarn prettier --write) and push the formatted file so the CI Prettier check
passes.

In `@wasm/src/ultrahdr/decoder.rs`:
- Around line 465-481: Replace the tautological Clippy-triggering assertion in
test_probe_never_panics: instead of asserting "result.width == 0 || result.width
> 0", assert that probe returned the expected zero width for these non-JPEG
inputs (e.g., assert_eq!(result.width, 0) or assert!(result.width == 0)); locate
this in the test function test_probe_never_panics and use the probe return value
(result.width) to make a meaningful check (you can also assert result.height ==
0 if appropriate).
- Around line 73-88: In probe_for_gain_map, the u32->usize casts for offset and
size can overflow on wasm32 and cause a slice panic; update the MPF branch
(where mpf_segment is handled and parse_mpf_for_gainmap returns (offset, size))
to perform checked arithmetic: convert to usize only after using checked_add (or
checked_add on usize) to ensure offset.checked_add(size) succeeds, and if it
returns None skip the MPF branch instead of slicing; ensure the subsequent
JpegParser::parse/gm dimensions logic only runs when the checked bounds test
passes.

Comment thread js/__tests__/probe.test.ts
Comment thread wasm/src/ultrahdr/decoder.rs
Comment thread wasm/src/ultrahdr/decoder.rs
- Run Prettier on probe.test.ts to fix formatting
- Fix tautological assertion in decoder.rs test (Clippy)
- Add checked arithmetic for potential overflow on wasm32 (Clippy)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@wasm/src/ultrahdr/decoder.rs`:
- Around line 25-37: The code sets result.has_primary_image before confirming
the JPEG structure, so if JpegParser::parse(data) fails you incorrectly report a
primary image; move the assignment of result.has_primary_image = true to after
the successful match arm of JpegParser::parse (i.e., only set it once you have
Ok(p)), leaving the initial magic-byte check as an early non-primary exit and
ensuring the Err(_) branch returns without mutating has_primary_image.

Comment thread wasm/src/ultrahdr/decoder.rs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@adamsilverstein
adamsilverstein merged commit 37b1d30 into main Jan 30, 2026
16 checks passed
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.

Add probe mode to efficiently detect UltraHDR images (inspired by libultrahdr)

1 participant