Skip to content

fix(pipeline): run Sharpen and the crop in their documented order (#109) - #112

Merged
StuartCameronCode merged 3 commits into
mainfrom
fix-109-sharpen-order-advice
Oct 5, 2026
Merged

StuartCameronCode merged 3 commits into
mainfrom
fix-109-sharpen-order-advice

Conversation

@StuartCameronCode

@StuartCameronCode StuartCameronCode commented Oct 5, 2026 •

Copy link
Copy Markdown
Owner

Fixes #109.

What was wrong

  • The Sharpen pass showed a warning that it "runs before Noise Reduction, so the denoiser will soften much of this again". That was false: Sharpen already ran after Noise Reduction, Chroma Denoise, Dehalo, Deblock, Deband and Anti-Aliasing.
  • Sharpen was not last, though. It ran ahead of Chroma Fixes, Colour Correction, Stabilize and Crop & Resize, so a downscale softened the sharpened edges again and an upscale enlarged the sharpening halos.

What changed

  • Removed the false warning from pass_advice.dart.

  • Moved Sharpen to after Crop & Resize and before Film Grain, in both .vpy templates, the Rust and Dart pass orders, and the pass list (it now sits at the top of "Finishing").

  • README and docs/ENGINEERING_NOTES.md record the new order and why.

  • Moved the crop from the top of both templates (ahead of Deinterlace) to directly before the resize, so the order is Stabilize → Rotate / Flip → Crop → Resize → Sharpen. Until now a crop could not remove the edges Stabilize exposes, although the comments, descriptions and tests all said it did.

Documentation

  • The README's "The filter pipeline" table is now numbered in the order the filters run, with notes on what a table cannot show: Crop & Resize is one step with the crop first, and custom code, colour conversion and borders follow the filters.
  • readme_pipeline_order_test.dart fails if that table and PassListPanel.stages disagree.
  • The README, code comments and in-app descriptions already said Stabilize runs last before cropping; that is now true (see below).

Behaviour changes

  • Presets and saved jobs that combine Sharpen with a resize, Stabilize, Chroma Fixes or Colour Correction render slightly differently than before.
  • Crop sides now refer to the picture after a rotation; they used to refer to the source. Saved jobs and presets combining a quarter turn with a crop will crop different edges.
  • Every pass before the crop works on the uncropped frame: slower with a crop, Edge Repair rebuilds the uncropped edge, and the automatic measurements (levels, white balance, chroma alignment) see the area the crop will remove, e.g. head-switching noise on a VHS capture. The effect on those measurements was not measured.
  • Sharpen now works at the output resolution: slower when upscaling, faster when downscaling.

Testing

  • flutter test --exclude-tags heavy: passes.
  • cargo test: passes except subtitle_integration_test, which needs whisper-cli and it is not installed locally.
  • Heavy: a new test in integration_new_passes_test.dart encodes each sharpen method after a resize and checks the output size; it and integration_filter_pipeline_test.dart pass. The rest of the heavy suite was not run locally.
  • test_110 (Rust) and pass_list_stages_test.dart now pin Sharpen after the resize and before the grain; pass_advice_test.dart asserts the Sharpen + Noise Reduction pair is silent.
  • Not covered: no preview was rendered with Sharpen after a resize. The preview template got the same move, but only the encode path was exercised.

🤖 Generated with Claude Code

https://claude.ai/code/session_014GLXdGLfPwgYjW1AkonGqN

StuartCameronCode and others added 3 commits October 5, 2026 21:11
…arning (#109)

The Sharpen pass warned that it "runs before Noise Reduction, so the
denoiser will soften much of this again". It never did: Sharpen already
ran after every clean-up pass. Remove the warning and pin the order the
remaining advice talks about against enabledPasses.

Sharpen was not last, though. It ran ahead of Chroma Fixes, Colour
Correction, Stabilize and the resize, so a downscale softened the
sharpened edges again and an upscale enlarged the halos. Move it to
after Crop & Resize and before Film Grain, in both templates, the Rust
and Dart pass orders and the pass list.

Presets and saved jobs that combine Sharpen with a resize render
slightly differently, and Sharpen now works at the output resolution.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014GLXdGLfPwgYjW1AkonGqN
The filter table was in no particular order, so the README never said
what the pipeline order is. Number the rows in run order, explain the
parts a table cannot show (the crop runs first, the resize late; custom
code, colour conversion and borders follow the filters), and pin the
table to PassListPanel.stages with a test.

Also correct the Stabilize row, which said a crop afterwards removes
the edges it exposes. The crop is applied before Deinterlace.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014GLXdGLfPwgYjW1AkonGqN
#109)

The crop was a separate block at the top of both templates, ahead of
Deinterlace, while the comments, the in-app descriptions and the README
all said Stabilize runs last before cropping so that a crop can remove
the edges it exposes. It could not.

Move the crop to directly before the resize, so the order is Stabilize,
Rotate / Flip, Crop, Resize, Sharpen. The pass now appears once in the
pass order, at that position.

Behaviour changes: crop sides refer to the picture after a rotation,
every earlier pass works on the uncropped frame, Edge Repair rebuilds
the uncropped edge, and the automatic measurements (levels, white
balance, chroma alignment) see the area the crop will remove.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014GLXdGLfPwgYjW1AkonGqN
@StuartCameronCode StuartCameronCode changed the title fix(pipeline): run Sharpen after the resize, and drop a false order warning (#109) fix(pipeline): run Sharpen and the crop in their documented order (#109) Oct 5, 2026
@StuartCameronCode
StuartCameronCode merged commit e4d6b3c into main Oct 5, 2026
11 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.

Sharpening workflow order

1 participant