Repository navigation
Wavelet fixes (CDF 9/7, fair bit estimates), DCT edge fixes, and viewer UX - #3
Merged
Merged
Conversation
Wavelets - Add CDF 9/7 (JPEG 2000 lossy wavelet) via lifting with symmetric extension, alongside Haar. TransformType is now DCT / DWT_HAAR / DWT_97 (WASM transform_mode 0 / 1 / 2; existing callers keep Haar for 1). - Quant steps shrink by 0.75 per coarser level instead of halving, which over-spent bits on coarse bands of a near-orthonormal transform. 0.75 gave the best PSNR at equal bitrate on the bundled test images. - Chroma wavelet bands use a 1.5x coarser step, mirroring the JPEG chroma/luma table ratio the DCT path already uses. - subbandMap() renders the quantized pyramid (zeroed coefficients dim). Bit estimate - Both paths now estimate bits from quantization indices (previously dequantized values) using per-subband zeroth-order entropy (EntropyEstimator). The old flat 0.5 bit/zero model floored every curve near 0.75 bpp, and DWT alone paid a 400-bit header, so the DCT-vs-DWT comparison was skewed. DCT / pipeline correctness - Partial edge blocks are padded by edge replication and coded instead of copied through untouched (inflated PSNR, uncounted bits). - DCT output is clamped to [0, 255]; quality is clamped to [1, 100] (quality <= 0 divided by zero). - Chroma upsampling is bilinear instead of nearest-neighbour. WASM - Cache the reconstructed BGR image so view switches skip colour conversion; add rd_encode/get_rd_bit_estimate for cheap RD sweeps that leave the displayed result untouched; add the Subbands view (7). - Drop the duplicate chroma downsampler in favour of ImageCodec::downsampleChannel. - Makefile builds EXPORTED_FUNCTIONS from a single WEB_EXPORTS list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Transform selector offers DCT / Haar / CDF 9/7 everywhere (transforms.ts is the single registry: labels, URL slugs, chart colours). - RD chart plots one curve per transform via rd_encode, so sampling no longer re-encodes and re-renders the displayed image afterwards. - Subbands view for wavelets, shown full-frame rather than behind the comparison split. The DCT-only block inspector is swapped for a "Wavelet Subbands" tool in wavelet mode instead of showing zeros; the inspector's broken DWT toggle is replaced with an explanation. - Settings sync to the URL hash (#q=30&t=cdf97&cs=420&v=subbands&img=3) and restore on load, including the bundled test image. Loading an image keeps the current quality instead of resetting to 50. - Download PNG of the processed view; [ / ] change quality by 5, T cycles the transform. - Tests: url-state, transforms, rdEncode unit tests; real-WASM browser test of all three transforms, rd_encode isolation and Subbands output. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- sanitize builds in build-sanitize/ instead of build/. The old recipe meant to drop the CMake cache but tested `-d` on a file, so ENABLE_SANITIZERS stayed cached and the next `make test` hung. - dev/test/coverage pass ENABLE_COVERAGE/ENABLE_SANITIZERS explicitly for the same reason. - Apple clang 17 on macOS 26 ships an ASan runtime that deadlocks before main (re-entrant malloc in InitializeShadowMemory). sanitize now runs a probe under a 10 s watchdog and falls back to UBSan only, with a warning. UBSan findings now fail the run. - New CI job runs the C++ suite under ASan + UBSan on Ubuntu and gates the web build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the DWT path, makes the DCT/DWT bitrate comparison fair, fixes DCT edge-case bugs, and adds several viewer features.
Codec (C++)
transform_modeis now 0 = DCT, 1 = Haar, 2 = CDF 9/7, so existing callers that pass 1 still get Haar.WASM bindings
rd_encodefor RD sweeps. It skips SSIM and leaves the displayed result untouched.MakefilebuildsEXPORTED_FUNCTIONSfrom a singleWEB_EXPORTSlist._set_artifact_gainwas missing from the old list.Web
transforms.tsis the single registry for labels, URL slugs and chart colours.#q=30&t=cdf97&cs=420&v=subbands&img=3) and restored on load.[/]change quality by 5,Tcycles the transform.Build / CI
make sanitizebuilds inbuild-sanitize/. The old recipe tested-don the cache file, so sanitizer flags stayed cached inbuild/and the nextmake testhung.dev,testandcoveragenow set their CMake flags explicitly, so one target's settings can't carry over to another.make sanitizedetects this with a 10 s probe and falls back to UBSan only.sanitize-nativeCI job runs ASan + UBSan on Ubuntu and gatesbuild-web.Behaviour changes
Test plan
make test: 52/52 GTest. New tests cover CDF 9/7 reconstruction and gain, subband indexing, coded edge blocks, pixel range, quality clamping, bits monotonic in quality, flat image ≈ 0 bits, 9/7 > Haar, subband map, and smooth chroma upsampling.make sanitizelocally: 52/52 under UBSan (ASan is unavailable on this toolchain, see above).npm run check: 0 errors, 0 warnings.npm run test: 193 unit tests. New:url-state,transforms,rdEncode.npm run test:browser: 42 tests, including a new real-WASM suite covering all three transforms,rd_encodeisolation and the Subbands output.sanitize-nativeCI job (ASan on Linux has not been run locally).Note
feature/motion-estimationhas this branch merged into it locally, with conflicts resolved, so it should merge cleanly after this PR lands.🤖 Generated with Claude Code