Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
58 changes: 57 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,11 @@ Adding a filter touches many files. Missing any step causes silent failures (fil
download URL becomes a red build instead of a silently-incomplete bundle.
- For local testing, run the download script to populate `deps/` (e.g.
`deps/windows-x64/vapoursynth/vs-plugins/`, `deps/macos-arm64/vapoursynth/plugins/`).
- **Credit it**: add an entry to `licenses/NOTICES.txt` and a `_ComponentTile`
to `app/lib/views/about_dialog.dart`, then map the binary's filename in
`app/test/attribution_test.dart` — that test fails until all three exist.
Take the copyright holder and licence from upstream, never from the handle or
the repo owner (see "Attribution" below).

### Regenerating the App Icon

Expand Down Expand Up @@ -794,7 +799,9 @@ cd app && flutter test # everything, incl. heavy (local

Headless Dart-VM tests. Three groups:
- **Pure unit tests** — `dynamic_parameters`, `filter_schema`,
`parameter_converter`, `widget_test`, `scan_type_detection`.
`parameter_converter`, `widget_test`, `scan_type_detection`,
`attribution` (NOTICES/About-dialog/deps-manifest agreement — see
"Attribution" below).
- **Shell-out tests** — `vapoursynth_integration_test`,
`schema_converter_integration_test`; need the per-arch `deps/` and (for whisper)
`addons/`.
Expand Down Expand Up @@ -868,6 +875,55 @@ integration tests. Matrix: macOS **arm64** (`macos-15`), macOS **x64**
gate — they run in `.github/workflows/nightly.yml` (cron + `workflow_dispatch`)
via `flutter test --tags heavy` on the same 4-platform matrix.

## Attribution — never write a name you have not read upstream

Third-party credit lives in **three** places that must agree:
`licenses/NOTICES.txt` (shipped in every package), the About dialog
(`app/lib/views/about_dialog.dart`), and the README's Acknowledgments.
`app/test/attribution_test.dart` lints the first two against
`Scripts/deps-expected-plugins.json`, so **adding a plugin without crediting it
fails the build** — the map in that test has to gain an entry too.

What the test cannot catch, and what actually shipped
([issue #72](https://github.com/StuartCameronCode/VapourBox/issues/72)):

> **zsmooth was credited to "Adrian Woracz" — a name that does not exist.** The
> author's GitHub handle is `adworacz`; his LICENSE says **Austin Dworaczyk
> Wiltshire**. The handle was expanded into a plausible-looking human name
> instead of being looked up, and it went out in the README, the About dialog
> and NOTICES simultaneously. The author found it and opened an issue.
>
> **Every copyright line must come from the upstream LICENSE file or a source
> header, fetched at the time of writing.** A GitHub handle is not a name. A
> repo owner is not necessarily the copyright holder. `gh api repos/<r>` gives
> the SPDX id, and the LICENSE / first 40 lines of the main source file give the
> holder — that is a 30-second check per component.

The 2026-08-17 audit that fixed it found the same class of error throughout,
which is why the whole file was rebuilt from upstream rather than patched:

- **Licences were wrong, not just names.** CTMF is GPL-3.0 (listed as 2.0),
DCTFilter is MIT (listed as GPL-2.0), AWarpSharp2 is ISC and RemoveGrain is
WTFPL (both listed as GPL-2.0). The bundled FFmpeg is built
`--enable-gpl --enable-version3`, so it is **GPL-3.0**, not the LGPL the file
claimed.
- **Year ranges were invented.** "Copyright (c) 2012-2024 …" appeared on
components whose upstream states no such range, including projects that
assert no copyright at all (havsfunc is Unlicense; FluxSmooth's author
explicitly disclaimed copyright).
- **It credited something not shipped** (ffms2, removed with BestSource) and
**omitted about fifteen plugins that are, or shortly will be** — Retinex,
bifrost, fluxsmooth, DeScratch, VIVTC, TCanny, TTempSmooth, AddGrain,
FFT3DFilter, KNLMeansCL, MiscFilters, TemporalMedian, BM3D, zimg, Zstandard,
and the Agner Fog VCL that eight HolyWu plugins compile in. Both directions
are now asserted.
- **`mvsfunc` has no licence at all upstream** — no LICENSE, no header. That is
now stated plainly rather than guessed as "Unlicense". Don't "tidy" it into a
licence name.

When a project genuinely states nothing, say so and offer to remove it on
request. An honest "no licence stated" is worth more than a confident guess.

## Code Style

### Rust
Expand Down
32 changes: 22 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,31 +186,43 @@ Stuart Cameron — [stuart-cameron.com](https://stuart-cameron.com)

## Acknowledgments

- **QTGMC** by Vit — the deinterlacing algorithm
- **QTGMC** by Vit, originally based on TempGaussMC_beta2 by Didée — the deinterlacing algorithm
- **VIVTC** by Fredrik Mellbin — VFM field matching and VDecimate for inverse telecine
- **VapourSynth** by Fredrik Mellbin — video processing framework
- **havsfunc** by HolyWu — QTGMC VapourSynth port
- **mvtools** by Manao, Fizick, Pinterf and dubhater — the motion estimation QTGMC is built on
- **havsfunc**, maintained by HolyWu — the VapourSynth script library QTGMC and many other passes come from
- **MVTools** — the motion estimation QTGMC is built on; VapourSynth port by dubhater, from the AviSynth plugin by Manao with later work by Fizick, Pinterf and the SVP team
- **NNEDI3** by Kevin Stone (tritical) — the edge-directed interpolator behind QTGMC, via **znedi3** by sekrit-twc and dubhater's **nnedi3**, whose NEON kernels are what make it fast on Apple Silicon and ARM Linux
- **akarin** — an LLVM-JIT expression evaluator. VapourSynth's own compiler for filter expressions is x86-only, so on ARM every expression was interpreted once per pixel; this is the single biggest reason Apple Silicon is now several times faster
- **fmtconv** by Firesledge — format conversion and resampling
- **zsmooth** by Adrian Woracz — chroma denoising (CCD) and the RemoveGrain family
- **whisper.cpp** by Georgi Gerganov — speech recognition for subtitle generation
- **akarin** by Akarin, now maintained by the Jaded Encoding Thaumaturgy project — an LLVM-JIT expression evaluator. VapourSynth's own compiler for filter expressions is x86-only, so on ARM every expression was interpreted once per pixel; this is the single biggest reason Apple Silicon is now several times faster
- **fmtconv** by Firesledge (Laurent de Soras) — format conversion and resampling
- **zsmooth** by Austin Dworaczyk Wiltshire — chroma denoising (CCD, originally written by Sergey Stolyarevsky for VirtualDub) and the RemoveGrain family
- **dubhater** — a long list of VapourSynth ports this app relies on: MVTools, nnedi3, AWarpSharp2, TemporalMedian, FluxSmooth, Bifrost and the `adjust` Tweak port
- **HolyWu** — the VapourSynth ports of DFTTest, TTempSmooth, TCanny, CTMF, DCTFilter, Deblock, AddGrain, CAS, EEDI3 and NNEDI3CL
- **mawen1250** — Retinex, BM3D and mvsfunc
- **whisper.cpp** by the ggml authors — speech recognition for subtitle generation
- **libdvdread** by VideoLAN — DVD reading and navigation
- **FFmpeg** project — video encoding
- **Hybrid** by Selur — inspiration for this project

Full licence texts and the complete list of bundled components are in
[`licenses/NOTICES.txt`](licenses/NOTICES.txt).
Full licence texts, copyright holders and the complete list of bundled
components are in [`licenses/NOTICES.txt`](licenses/NOTICES.txt). If any
attribution there is wrong or names you incorrectly, please
[open an issue](https://github.com/StuartCameronCode/VapourBox/issues) — it will
be fixed.

<details>
<summary><b>Pre-built binary sources</b></summary>

macOS plugins and binaries sourced from:
Where a component is taken pre-built rather than compiled from source, it comes
unmodified from one of these, and thanks are owed to the people who maintain
them:

- **[yuygfgg/Macos_vapoursynth_plugins](https://github.com/yuygfgg/Macos_vapoursynth_plugins)** — pre-built ARM64 VapourSynth plugins for macOS
- **[Stefan-Olt/vs-plugin-build](https://github.com/Stefan-Olt/vs-plugin-build)** — cross-platform VapourSynth plugins (arm64 + x86_64; used for `tmedian`)
- **[evermeet.cx](https://evermeet.cx/ffmpeg/)** — static x86_64 FFmpeg/FFprobe builds for the Intel macOS bundle
- **[ffmpeg.martin-riedl.de](https://ffmpeg.martin-riedl.de)** — static arm64 FFmpeg/FFprobe builds for the Apple Silicon bundle
- **[BtbN/FFmpeg-Builds](https://github.com/BtbN/FFmpeg-Builds)** — static FFmpeg/FFprobe builds for Windows and Linux
- **[python-build-standalone](https://github.com/astral-sh/python-build-standalone)** — the relocatable CPython used on macOS and Linux
- **[Homebrew](https://brew.sh)** — the `whisper-cpp` bottle used for the macOS speech-recognition add-on

The Intel (x64) bundle additionally builds its support libraries (zimg, fftw, libdvdread, boost) from source targeting **macOS 12**, so it runs on Monterey; the Apple Silicon (arm64) bundle is built for the current macOS and targets **macOS 15**.

Expand Down
Loading
Loading