Metadata-Version: 2.4
Name: vapoursynth-autocrop
Version: 2.0
Summary: Automatic border cropping filter for VapourSynth
Keywords: video,crop,letterbox,pillarbox
Author-Email: Infiziert90 <infiziert@protonmail.ch>
Maintainer-Email: Fredrik Mellbin <fredrik.mellbin@gmail.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Plugins
Classifier: Natural Language :: English
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: Operating System :: Unix
Classifier: Programming Language :: C++
Classifier: Topic :: Multimedia :: Video
Project-URL: Repository, https://github.com/myrsloik/vapoursynth-autocrop.git
Project-URL: Issues, https://github.com/myrsloik/vapoursynth-autocrop/issues
Requires-Python: >=3.12
Requires-Dist: VapourSynth
Description-Content-Type: text/markdown

# vapoursynth-autocrop
AutoCrop for Vapoursynth

# Usage  
AutoCrop  
```python
acrop.AutoCrop(clip src, int range=4, int top=range, int bottom=range, int left=range, int right=range, float[] ref_color=<black luma, neutral chroma>, float[] max_color_deviation=[0.0824,0.0196,0.0196])
```  

Search only  
```python
acrop.CropValues(clip src, int range=4, int top=range, int bottom=range, int left=range, int right=range, float[] ref_color=<black luma, neutral chroma>, float[] max_color_deviation=[0.0824,0.0196,0.0196])
```

`CropValues` leaves the frame untouched and only attaches the detected values as the
frame properties `CropTopValue`, `CropBottomValue`, `CropLeftValue` and `CropRightValue`.
`AutoCrop` applies the crop instead. Because the amount to crop is decided per frame,
`AutoCrop` produces a clip with variable dimensions, which many filters refuse to accept.

## Arguments

Input must be constant format YUV or GRAY, either 8 to 16 bit integer or 32 bit float.
16 bit half float is not supported. All chroma subsamplings are supported. A GRAY clip
has nothing to constrain the crop besides its single plane, and since it has no
subsampling, crop values on it are not restricted to even numbers.

`range` sets the default for `top`, `bottom`, `left` and `right`, which cap how far in
from each edge the search looks. They must be non-negative, must be a multiple of the
chroma subsampling, and must leave at least one pixel in each direction, so
`left + right < width` and `top + bottom < height`.

`ref_color` is the color a border is expected to be and `max_color_deviation` is how
far a sample may stray from it before the row or column stops counting as border.

`ref_color` takes one value per plane as an actual sample value in the clip's own scale,
with no conversion applied. An integer clip wants values inside its sample range, so
neutral chroma is 128 at 8 bit and 32768 at 16 bit. A float clip wants normalised values,
where luma and GRAY run 0.0 to 1.0 while chroma runs -0.5 to 0.5, so neutral chroma there
is 0.0 and negative references are perfectly valid.

Its default is black luma and neutral chroma expressed for whatever format the clip is,
so leaving it alone means the same thing everywhere.

`max_color_deviation` is a fraction of the full sample range rather than a sample value,
either a single value applied to every plane or one value per plane. For integer clips
the tolerance is `round(max_color_deviation * ((1 << bits_per_sample) - 1))`, and for
float clips the full range is 1.0 so the tolerance is the deviation itself. A deviation
of 0.0 requires an exact match and 1.0 accepts anything.

Together the defaults accept luma 0 to 21 and chroma 128 +/- 5 at 8 bit, which is the
same band the original `color`/`color_second` pair described, and the equivalent band at
every other depth and sample type.

Each edge is measured independently over the full frame, and the result is not fed back
into the other edges. A sample outside the color range therefore blocks detection along
the whole row and column it sits in, even if it would itself have been cropped away by
one of the other edges.

## Compilation

The plugin builds with Meson through a PEP 517 frontend, which installs it straight
into the VapourSynth plugin directory of the Python environment it is built for:

```
pip install .
```

To produce a wheel instead:

```
python -m build
```

The VapourSynth Python module has to be installed in the build environment, since the
build queries it for the header location.

Meson can also be driven directly if you would rather not go through Python packaging:

```
meson setup build && meson compile -C build
```
