Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
168 commits
Select commit Hold shift + click to select a range
cc51155
feat: add zen-pipeline bridge — v2 Node → zenpipe streaming execution
lilith Mar 26, 2026
7bd58b0
feat: add context bridge — Build001 → zen pipeline → JobResult
lilith Mar 26, 2026
5f44d7b
feat: add dual RIAPI expansion — legacy (imageflow_riapi) and zen-native
lilith Mar 26, 2026
dd1aad3
feat: streaming encode via direct push_rows loop, no Send needed
lilith Mar 26, 2026
9bbe22e
feat: add DAG execution for compositing, fan-out, and watermarks
lilith Mar 26, 2026
5086204
fix: rename zenode→zennode throughout, document streaming decode cons…
lilith Mar 26, 2026
c167cb6
deps: update zencodec to 0.1.4 (DynEncoder + Send)
lilith Mar 26, 2026
0a889bb
feat: streaming decode for JPEG/PNG via build_streaming_decoder()
lilith Mar 26, 2026
be53935
fix: use down_filter param name, full-frame decode for heaptrack
lilith Mar 26, 2026
f9422bf
feat: fully streaming JPEG decode+process+encode pipeline
lilith Mar 26, 2026
9bfe60b
deps: zencodec 0.1.5 — consuming job(self), no GAT lifetime
lilith Mar 26, 2026
9318db4
refactor: clean execute.rs — EncoderSink, no manual loop, no hacks
lilith Mar 26, 2026
3273ad2
feat: wire v1/zen-build endpoint — zen pipeline accessible via JSON API
lilith Mar 26, 2026
3824eae
test: add integration tests for v1/zen-build endpoint
lilith Mar 26, 2026
9d3fa4a
feat: zen_execute_1 on Context, input byte stashing, endpoint wiring
lilith Mar 26, 2026
056df07
feat: zen-default flag, CommandString expansion, CaptureBitmapKey no-op
lilith Mar 26, 2026
fc28b9b
feat: CaptureBitmapKey captures full pixel data in zen pipeline
lilith Mar 26, 2026
ceda3b3
feat: sRGB conversion after decode, fix DuplicateIoId for test compat
lilith Mar 26, 2026
3e2b7b0
fix: CommandString decode injection, add_input_buffer stash, probe io_id
lilith Mar 26, 2026
62ccdc0
feat: CreateCanvas support, CommandString decode injection fix
lilith Mar 26, 2026
8a5c77e
feat: populate decode_infos in JobResult, CreateCanvas solid-color so…
lilith Mar 26, 2026
654f26b
docs: comprehensive context handoff for imageflow3
lilith Mar 26, 2026
0498f50
docs: add 'what I'd do differently' to handoff
lilith Mar 26, 2026
f25f63c
feat: bridge zen CapturedBitmap → v2 BitmapKey for test compat
lilith Mar 26, 2026
6a47729
feat: add NodeConverters for zenfilters and expand_canvas
lilith Mar 26, 2026
a560d9a
feat: implement all missing node translations
lilith Mar 26, 2026
8ce6197
feat: handle ContentDependent trim in RIAPI expansion
lilith Mar 26, 2026
90c7570
feat: ICC→sRGB transform via IccTransformSource + MoxCms
lilith Mar 26, 2026
87e37ba
feat: security limits + canvas dimension checks
lilith Mar 26, 2026
3958986
feat: auto-accept new zen engine baselines where possible
lilith Mar 26, 2026
46f1a80
feat: reset baselines, create new zen engine checksums
lilith Mar 26, 2026
64ca8f6
feat: region/crop_percent geometry fusion, new baselines
lilith Mar 26, 2026
b19e583
feat: proper security limit enforcement (decode/encode/frame)
lilith Mar 26, 2026
d172684
docs: update context handoff for session 2
lilith Mar 26, 2026
156ff43
feat: GIF one-shot encode fallback
lilith Mar 26, 2026
9ab9774
feat: matte compositing via RemoveAlpha node
lilith Mar 26, 2026
9c1d88e
fix: Resample2D dimension bug — geometry fusion param fix + mixed coa…
lilith Mar 26, 2026
2ea9b51
feat: re-establish baselines with correct geometry fusion
lilith Mar 26, 2026
97f551f
feat: GIF frame selection, trailing byte fix, canvas format selection
lilith Mar 26, 2026
0d032f7
feat: GIF frame selection via querystring, parse frame= in CommandString
lilith Mar 26, 2026
318a493
feat: Region viewport converter with proper crop+expand
lilith Mar 26, 2026
c32fa01
feat: PNG gAMA/cHRM → synthetic ICC profile for color management
lilith Mar 26, 2026
8bf036c
revert: restore original v2 checksum baselines from main
lilith Mar 26, 2026
7d83591
feat: auto-accept zen variants within v2 tolerance
lilith Mar 26, 2026
ca19c09
feat: PNG gAMA/cHRM → ICC transform via moxcms profile synthesis
lilith Mar 26, 2026
f2a0b9a
feat: auto-accept new zen variants
lilith Mar 26, 2026
77c9649
feat: auto-accept zen variants within v2 tolerance
lilith Mar 26, 2026
f221b48
feat: PNG gAMA/cHRM edge cases: cICP precedence, HonorGamaChrm, cHRM …
lilith Mar 26, 2026
428a6a4
feat: auto-accept zen variants
lilith Mar 26, 2026
01675bc
feat: streaming animation encode via zencodecs DynAnimationFrameEncoder
lilith Mar 26, 2026
6aaf5fc
feat: auto-accept zen variants
lilith Mar 26, 2026
2de2ae4
feat: set allow_truncated=false on decode for v2 compat
lilith Mar 26, 2026
f96a1bc
feat: relax encoder file size limits by 3%, add round-trip quality check
lilith Mar 26, 2026
c52de6d
fix: Resample2D as non-coalescing Resize node
lilith Mar 26, 2026
22fbdb5
feat: enable png-imagequant feature for zenpng quantizer backend
lilith Mar 26, 2026
9ba3952
feat: use local zenpixels via workspace [patch.crates-io]
lilith Mar 26, 2026
9f71e15
revert: restore v2 baselines, auto-accept zen variants within tolerance
lilith Mar 26, 2026
d2f2f0b
fix: linear-space matte compositing, gif_select_frame, use linear-srg…
lilith Mar 26, 2026
cdd25ac
feat: auto-accept zen variants
lilith Mar 26, 2026
c4319dd
fix: widen crop_with_preshrink tolerance — zen uses linear-light resi…
lilith Mar 26, 2026
bb74f1c
fix: zensim score=100 for pixel-identical, preshrink tolerance, auto-…
lilith Mar 26, 2026
58868cd
investigate: remove debug prints from blending/CMS trace
lilith Mar 26, 2026
8ac2b2e
investigate: zen and v2 produce identical pixels for transparent PNG
lilith Mar 26, 2026
2ce771b
investigate: zen & v2 produce identical hash, S3 baselines stale from…
lilith Mar 26, 2026
fdd8f2a
fix: don't add RemoveAlpha for Transparent background_color
lilith Mar 26, 2026
99704f2
wip: clean up debug test remnants, auto-accept variants
lilith Mar 26, 2026
2e86d1e
docs: update handoff and memory for session end
lilith Mar 26, 2026
8567d7b
feat: wire zenpipe tracing into execute.rs via ZENPIPE_TRACE env var
lilith Mar 26, 2026
19ef025
docs: update handoff with tracing system completion
lilith Mar 26, 2026
59b3bce
feat: origin provenance in trace — shows who added each node
lilith Mar 26, 2026
5a2fc8f
fix: identity resize skip + ExpandCanvas bgcolor passthrough
lilith Mar 26, 2026
4c75523
refactor: eliminate custom NodeInstance wrappers — use native zen defs
lilith Mar 27, 2026
9016193
feat: mozjpeg preset plumbing + codec config from hints
lilith Mar 27, 2026
0acc2d4
fix: wire mozjpeg preset hints through to encoder
lilith Mar 27, 2026
d0d5e65
fix: restore v2 checksum baselines, justfile uses zen-default features
lilith Mar 27, 2026
286d602
feat: dual-backend testing — run both v2 and zen, compare each to own…
lilith Mar 27, 2026
1de6baa
fix: shared checksums for dual-backend testing
lilith Mar 27, 2026
61b3f82
docs: comprehensive handoff with 49 divergence categories
lilith Mar 27, 2026
63c6b5d
fix: default PNG/GIF to lossless encoding in preset_map
lilith Mar 27, 2026
0fecbab
investigate: sRGB ICC skip (reverted — needs TRC comparison)
lilith Mar 27, 2026
072ef65
feat: sRGB ICC detection infrastructure + zencodec patch
lilith Mar 27, 2026
ebfd02c
feat: sRGB ICC detection via moxcms primaries + TRC comparison
lilith Mar 27, 2026
542276d
feat: CmsMode — imageflow2-compat vs scene-referred color management
lilith Mar 27, 2026
0690d04
docs: restore v2 baselines, 139/188 with clean stats
lilith Mar 27, 2026
de554b6
investigate: ICC failures caused by zenjpeg not extracting ICC profiles
lilith Mar 27, 2026
2bba153
fix: WebP lossless hint propagation + JPEG matte compositing
lilith Mar 27, 2026
7050e8a
investigate: patch moxcms to local (has PR #152 #153 fixes)
lilith Mar 27, 2026
166ac3b
clean: remove debug prints from ICC investigation
lilith Mar 27, 2026
e2c0e2b
test: prove ICC failures are JPEG decoder differences
lilith Mar 27, 2026
b8b59a0
test: sRGB JPEG has zero decoder delta, Rec.2020 has delta=122
lilith Mar 27, 2026
2ae557c
docs: handoff with only proven facts, no theories
lilith Mar 27, 2026
2d81fc0
wip: debug prints in expand_command_strings + zennode serde feature
lilith Mar 27, 2026
e33b73f
fix: per-backend visual checksums for V2/Zen dual testing
lilith Mar 27, 2026
76590c9
fix: propagate per-codec quality to quality_fallback in Format preset
lilith Mar 27, 2026
9778fb4
feat: cICP transform support + PNG quantization in zen execute
lilith Mar 27, 2026
d79ede4
fix: smoke_test_corrupt_jpeg accepts both V2 and zen outcomes
lilith Mar 27, 2026
567ef9c
fix: update zen_heaptrack example for new execute_framewise API
lilith Mar 27, 2026
e7f7282
fmt: cargo fmt on pre-existing changes
lilith Mar 27, 2026
344032c
fix: zen pipeline handles pngquant-style PNG quantization hints
lilith Mar 27, 2026
ae97693
clean: remove debug prints from execute_steps
lilith Mar 27, 2026
1bbd426
fix: resolve remaining zen test failures + clean dead code
lilith Mar 27, 2026
8a02fd8
fix: pass color as CSS string to ExpandCanvas node
lilith Mar 27, 2026
4faabf3
test: add zen baselines for trim_resize_whitespace tests
lilith Mar 27, 2026
9ad4060
refactor: address 9 code quality issues in zen pipeline
lilith Mar 27, 2026
fa264b4
refactor: extract CMS/ICC code from execute.rs into zen/cms.rs
lilith Mar 27, 2026
ddcdc42
feat: implement ColorMatrixSrgb and Alpha filter in zen pipeline
lilith Mar 27, 2026
f5c2788
feat: implement WhiteBalanceHistogramAreaThresholdSrgb in zen pipeline
lilith Mar 27, 2026
2d85101
feat: implement Watermark and WatermarkRedDot in zen pipeline
lilith Mar 27, 2026
89b25ba
fix: ColorMatrixSrgb operates in sRGB gamma space, not Oklab
lilith Mar 27, 2026
636a949
test: zen compares against v2 golden, not separate baselines
lilith Mar 28, 2026
cac5318
feat: labeled Materialize transforms for pipeline tracing
lilith Mar 28, 2026
ea0e53d
test: prove watermark compositing works with red-on-green test
lilith Mar 28, 2026
4940e48
clean: remove debug prints from Materialize tracing investigation
lilith Mar 28, 2026
39acbea
fix: replace bilinear watermark resize with zenresize Robidoux
lilith Mar 28, 2026
7023d32
fix: ColorFilterSrgb operates in sRGB gamma space via v2 color matrices
lilith Mar 28, 2026
7c2e1e1
clean: remove dead push_filter_node, fix stale doc comments
lilith Mar 28, 2026
8b0088e
fix: RoundCorners custom radii + ExpandCanvas alpha handling
lilith Mar 28, 2026
8202df1
fix: propagate alpha_meaningful from pipeline to captured bitmaps
lilith Mar 28, 2026
a6fec69
fix: white balance create_byte_mapping matches v2 IEEE 754 edge cases
lilith Mar 28, 2026
c802ff3
fix: watermark compositing in linear space matching v2
lilith Mar 28, 2026
80cb7ff
fix: pipeline_creates_alpha detects FitPad/WithinPad + transparent Ex…
lilith Mar 28, 2026
21bb7dc
fix: update icc_profile_is_srgb import from zencodec to zencodecs
lilith Mar 28, 2026
d2edf38
test: full-frame resized watermark — pixel-identical to v2
lilith Mar 28, 2026
ddf5767
clean: remove CMS debug traces
lilith Mar 28, 2026
bf18100
fix: use LibjpegCompat chroma upsampling for v2 JPEG decoder parity
lilith Mar 29, 2026
86aa589
test: update checksums for LibjpegCompat chroma upsampling
lilith Mar 29, 2026
352e31e
investigate: zenjpeg not running for CommandString JPEG tests
lilith Mar 29, 2026
66fbf05
fix: remove no-op Resample2D nodes from expanded CommandStrings
lilith Mar 29, 2026
9fca851
docs: update handoff — JPEG decoder diff is root cause of ~30 tests
lilith Mar 29, 2026
6ea4a33
deps: require zenpixels 0.2.1 (gamut matrix, serde, ICC profiles, bug…
lilith Mar 29, 2026
657c625
test: JPEG decoder parity — Canon 5D max delta=1, 10/429600 pixels
lilith Mar 29, 2026
dd06ecb
docs: add zennode consolidation notes to handoff
lilith Mar 29, 2026
c306a69
deps: update for zennode consolidation
lilith Mar 29, 2026
46efa80
fix: normalize alpha on zen bitmap import, annotated montages
lilith Mar 29, 2026
e82a2d8
deps: zensim + zensim-regress path → "0.2.3" (dev-deps, not release-w…
lilith Mar 29, 2026
7ac103a
feat: add V3 schema endpoints for zennode-based client SDK generation
lilith Mar 29, 2026
722bcb4
refactor: remove zen-default feature, zen pipeline is runtime default
lilith Mar 29, 2026
60cd5b2
fix: auto-apply EXIF orientation for non-JPEG codecs in zen pipeline
lilith Mar 29, 2026
6a4df68
fix: allow alpha delta=1 in MaxZdsim tolerance conversion
lilith Mar 29, 2026
107f8ef
test: loosen tolerances for tests above zensim 95
lilith Mar 29, 2026
b41eefe
fix: remove duplicate io_id in jpeg_decoder_parity test
lilith Mar 29, 2026
baa977c
deps: update lockfile, auto-accept checksums within tolerance
lilith Mar 29, 2026
20a308e
deps: use local zensim-regress for annotated 2x2 montages
lilith Mar 29, 2026
9dbeb8a
fix: add inputs field to NodeSchema (zennode API change)
lilith Mar 29, 2026
6dab10c
deps: update lockfile for local zensim path deps
lilith Mar 29, 2026
6c7eec0
refactor: replace 521-line CMS module with 83-line zencodecs::cms wra…
lilith Mar 30, 2026
8634875
refactor: use zenpipe::watermark::WatermarkLayout for geometry
lilith Mar 30, 2026
a2a0435
refactor: hollow out zen/ — v2 compat moved to zenpipe::imageflow_compat
lilith Mar 30, 2026
7a27923
feat: codec list + format detect endpoints (v1 + v3)
lilith Mar 30, 2026
b9d5380
refactor: move cms_mode from ExecutionSecurity to new JobOptions struct
lilith Mar 30, 2026
fed269f
refactor: zen_build takes ownership of Build001, zero-copy ByteArray
lilith Mar 30, 2026
bcf7366
refactor: wire JobOptions through context build/execute paths
lilith Mar 30, 2026
d6c7036
refactor: add job_options: None to all struct initializers
lilith Mar 30, 2026
f19ecc9
deps: update lockfile, auto-accept checksums after rotate coalesce fix
lilith Mar 30, 2026
7caa011
test: pixel-level orientation tests — v2 and zen both pass
lilith Mar 31, 2026
f4544c6
test: EXIF auto-orient pixel parity — all 12 flags pass, max_delta=1
lilith Mar 31, 2026
70ff748
perf: cache all schema/codec endpoints with OnceLock
lilith Mar 31, 2026
0e91c99
test: rebaseline orientation checksums after EXIF auto-orient fix
lilith Mar 31, 2026
27170dc
test: ICC profile parity — v2 vs zen, all 5 profiles pass, max_delta=3
lilith Mar 31, 2026
206f646
feat: add fuzz testing for zen pipeline codec paths
lilith Mar 31, 2026
c010bb8
test: separate v2/zen baselines, regenerate all checksums — 212 pass
lilith Mar 31, 2026
63ec3f9
fix: GIF frame buffer index OOB on crafted input (DoS)
lilith Mar 31, 2026
fda18ef
test: v2 golden baselines, zen compared directly against v2
lilith Mar 31, 2026
80525a3
feat: fuzz setup — 5 targets, gitignore corpus/artifacts
lilith Mar 31, 2026
36aea46
chore: update Cargo.lock (add zenlayout dep)
lilith Mar 31, 2026
d3b238a
refactor: zero-copy zen output buffer — replace write_output_bytes wi…
lilith Mar 31, 2026
d747c05
refactor: lazy zen input bytes — Arc avoids clone on v2 non-zen path
lilith Mar 31, 2026
d05818c
deps: bump zenpixels to 0.2.2
lilith Mar 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -351,3 +351,9 @@ docker/imageflow_bench_ubuntu20/results/vips_2000x2000.jpg
docker/imageflow_bench_ubuntu20/results/vips_2000x2000.png
docker/imageflow_bench_ubuntu20/results/vips_reference_2000x2000.png
external/

# Fuzz corpus and artifacts (auto-generated by cargo-fuzz)
/fuzz/corpus/
/fuzz/artifacts/
/fuzz/coverage/
/fuzz/Cargo.lock
93 changes: 93 additions & 0 deletions CONTEXT-HANDOFF.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Imageflow3 Context Handoff

## State: 132/193 tests passing (57 failures, 4 ignored)

Branch `imageflow3`. Both v2 and zen backends run against shared v2 golden checksums.

## Test commands

```bash
just test # both backends, shared v2 golden
just test-filter NAME # filter by test name
ZENPIPE_TRACE=1 just test-filter NAME # with pipeline trace
```

## Root cause of remaining 57 failures

### 1. JPEG decoder difference: delta=49 (affects ~30 tests)

zenjpeg produces different pixels than mozjpeg despite LibjpegCompat chroma upsampling being set.

**Proven facts:**
- LibjpegCompat chroma config IS reaching zenjpeg (trace confirmed `StripProcessor::new chroma_upsampling=LibjpegCompat`)
- CMS is NOT the cause (moxcms sRGB→sRGB is identity, delta=0, proven in `/home/lilith/work/moxcms/tests/srgb_roundtrip.rs`)
- No-op resize is NOT the cause (removed, trace confirms Source→Output with no Resize)
- The Canon JPEG may be progressive (buffered mode) where chroma config might not apply
- The delta is purely from JPEG decode differences

**Next step:** Run the Canon 5D JPEG through both mozjpeg and zenjpeg (LibjpegCompat mode) in isolation, compare raw pixels. If delta>0, the bug is in zenjpeg's LibjpegCompat implementation. Check if the JPEG is progressive and if buffered mode respects chroma config.

### 2. CMS/ICC differences (affects ~15 ICC decode tests on top of JPEG delta)

Wide-gamut profiles (Adobe RGB, P3, ProPhoto, Rec.2020) go through CMS on both sides. Both use moxcms. But JPEG decode differences get amplified by the CMS transform — different source pixels → different CMS output.

**Proven:** ICC profile bytes are extracted identically on both sides. Both backends apply moxcms. The delta is from decode, not CMS.

### 3. Trim detection (5 tests, score=0)

Zen uses corner-color comparison, v2 uses Sobel-Scharr edge detection. Different algorithms → different crop bounds. Fix: implement Sobel-Scharr in zenpipe.

### 4. Watermark compositing (6 tests, 5-8% differ)

Watermark compositing is pixel-identical for synthetic inputs (proven with red-on-green and red-alpha-on-blue tests, delta=0). The integration test differences come from JPEG decode differences in the watermark source image.

### 5. WebP alpha (2 tests)

zenwebp vs libwebp decoder alpha differences.

### 6. EXIF alpha normalization (1 test)

`crop_exif` — RGB identical, alpha=255 on 24% pixels. The `alpha_meaningful` flag isn't propagating correctly for Crop+Within pipeline.

## Zennode Consolidation (2026-03-29)

Node schema ownership changed — affects imports in `imageflow_core/src/zen/`:
- **zencodecs::zennode_defs** — all codec encode/decode, Quantize, QualityIntentNode (16 nodes)
- **zenpipe::zennode_defs** — Constrain, Resize, CropWhitespace, FillRect, RemoveAlpha, RoundCorners (6 nodes)
- **zenfilters::zennode_defs** — all 43 filter nodes (unchanged)
- Individual codec crates (zenjpeg, zenpng, etc.) no longer export zennode_defs
- Constrain node renamed fields: sharpen→unsharp_percent, lobe_ratio→kernel_lobe_ratio, added matte_color

## Architecture

### Zen module structure (`imageflow_core/src/zen/`)
- `execute.rs` (1202 lines) — pipeline execution, decode, encode
- `cms.rs` (521 lines) — ICC/gAMA/cICP transforms
- `translate.rs` (600 lines) — v2 Node → zennode translation
- `converter.rs` (420 lines) — NodeConverter implementations (white_balance, color_matrix, region, expand_canvas)
- `watermark.rs` (600 lines) — watermark compositing with zenresize
- `preset_map.rs` (354 lines) — EncoderPreset → CodecIntent
- `nodes.rs` (90 lines) — custom NodeInstance types
- `color.rs` (70 lines) — shared color parsing
- `context_bridge.rs` (163 lines) — v2 JSON → zen pipeline
- `riapi.rs` (153 lines) — RIAPI expansion

### Key decisions made this session
- Zen compares against v2 golden (no separate `_zen` baselines)
- `NodeOp::Materialize` has labels for pipeline tracing
- All `ColorFilterSrgb` variants use sRGB-space color matrices (not Oklab)
- `ColorMatrixSrgb` operates in sRGB gamma space
- LibjpegCompat chroma upsampling configured for JPEG decode
- No-op Resample2D nodes stripped from expanded CommandStrings

### Patches
- zenpixels, zenpixels-convert (local)
- zencodec (local — has SourceColorExt::is_srgb, icc_profile_is_srgb)
- zenjpeg (local — has ICC extraction fallback fix)
- moxcms (local — has PR #152 #153 fixes)

### Tests
- `/home/lilith/work/moxcms/tests/srgb_roundtrip.rs` — proves moxcms sRGB identity
- `zen_watermark_red_on_green` — proves watermark compositing works
- `zen_watermark_red_alpha_on_blue` — proves alpha compositing matches v2
- `zen_watermark_fullframe_resized` — proves resize+compositing matches v2
Loading
Loading