diff --git a/.coverage b/.coverage
new file mode 100644
index 0000000..7437710
Binary files /dev/null and b/.coverage differ
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..ec4a626
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.pth filter=lfs diff=lfs merge=lfs -text
diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml
new file mode 100644
index 0000000..1cddd8d
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yaml
@@ -0,0 +1,71 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+#
+# ******** NOTE ********
+# We have attempted to detect the languages in your repository. Please check
+# the `language` matrix defined below to confirm you have the correct set of
+# supported CodeQL languages.
+#
+name: "CodeQL"
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [ main ]
+ schedule:
+ - cron: '40 7 * * 0'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ 'python' ]
+ # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
+ # Learn more:
+ # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v1
+ with:
+ languages: ${{ matrix.language }}
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+ # queries: ./path/to/local/query, your-org/your-repo/queries@main
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v1
+
+ # ℹ️ Command-line programs to run using the OS shell.
+ # 📚 https://git.io/JvXDl
+
+ # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
+ # and modify them (or add more) to build your code if your project
+ # uses a compiled language
+
+ #- run: |
+ # make bootstrap
+ # make release
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v1
diff --git a/.github/workflows/python-package.yaml b/.github/workflows/python-package.yaml
new file mode 100644
index 0000000..db58593
--- /dev/null
+++ b/.github/workflows/python-package.yaml
@@ -0,0 +1,45 @@
+name: Python package
+
+on: [push, pull_request]
+
+jobs:
+ build:
+
+ runs-on: windows-latest
+ strategy:
+ max-parallel: 4
+ matrix:
+ python-version: ['3.10']
+
+ steps:
+ - name: Support longpaths
+ run: git config --system core.longpaths true
+ - uses: actions/checkout@v1
+ with:
+ lfs: 'true'
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v1
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ python -m pip install -e .[test]
+ - name: Checkout submodule
+ run: |
+ git submodule sync
+ git submodule update --init --recursive
+ - name: Lint with flake8
+ run: |
+ # stop the build if there are Python syntax errors or undefined names
+ flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
+ # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
+ flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
+ - name: Test with pytest
+ run: |
+ pytest --cov=bimana --cov-report term-missing --cov-report lcov tests/
+ - name: Coveralls
+ uses: coverallsapp/github-action@master
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ path-to-lcov: ./coverage.lcov
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8c25ef6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+
+.vscode/
+
+bimana.egg-info/
+
+*.pyc
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..e847094
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "third_party/DexiNed"]
+ path = third_party/DexiNed
+ url = https://github.com/AlphonsG/DexiNed
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..a40e181
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,34 @@
+# How to contribute to Bimana
+
+:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
+
+## Report issues or problems with the software
+
+* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/AlphonsG/BIMANA/issues).
+
+* If you're unable to find an open issue addressing the problem, use the relevant bug report [template](https://github.com/AlphonsG/BIMANA/issues/new/choose) to create one.
+
+* If not possible, you can [open a blank issue](https://github.com/AlphonsG/BIMANA/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring.
+
+## Submitting Changes
+
+* Open a new GitHub pull request with the change.
+
+* Ensure the PR description clearly describes the change. Include the relevant issue number if applicable.
+
+* At lease one reviewer should be added so that the code is looked over by someone else.
+
+Always write a clear log message for your commits, for example:
+
+ $ git commit -m "A brief summary of the commit
+ >
+ > A paragraph describing what changed and its impact."
+
+ ## Coding conventions
+
+ Please follow the [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html) when contributing to the code.
+
+ ## Seek Support
+
+ Please feel free to send an email to the following address for other matters:
+ - 0go0vdp95@mozmail.com
diff --git a/README.md b/README.md
index ff4a40d..13a49af 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,119 @@
-# BIMANA
\ No newline at end of file
+# Bimana
+
+[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
+[![Python package](https://github.com/AlphonsG/BIMANA/actions/workflows/python-package.yaml/badge.svg?branch=dev)](https://github.com/AlphonsG/BIMANA/actions/workflows/python-package.yaml)
+[![Coverage
+Status](https://coveralls.io/repos/github/AlphonsG/BIMANA/badge.svg?branch=dev)](https://coveralls.io/github/AlphonsG/BIMANA?branch=dev)
+[![CodeFactor](https://www.codefactor.io/repository/github/alphonsg/bimana/badge/dev)](https://www.codefactor.io/repository/github/alphonsg/bimana/overview/dev)
+[![GitHub license](https://img.shields.io/github/license/AlphonsG/BIMANA)](https://github.com/AlphonsG/BIMANA/blob/main/LICENSE)
+
+![](misc/images/bimana.png?raw=true "Bimana Image Analysis")
+
+Package for performing automated bio-image analysis tasks.
+
+# Table of contents
+1. Installation
+2. Usage
+3. License
+4. Community Guidelines
+5. Acknowledgements
+## Installation
+
+Bimana can be installed on Linux, Windows (with 64 bit Python) & macOS and
+supports Python 3.10 and above. It is recommended to install and run Bimana
+within a [virtual environment](https://docs.python.org/3/tutorial/venv.html).
+
+1. Download and install [Python](https://www.python.org/downloads/) (Bimana was
+ tested using [Python version
+ 3.10.6](https://www.python.org/downloads/release/python-3106/)),
+ [Git](https://git-scm.com/) and [Git LFS](https://git-lfs.github.com/).
+ Linux and macOS users must also install [libvips](https://www.libvips.org/install.html).
+
+2. Launch the terminal (*Linux* and *macOS* users) or command prompt (*Windows* users). The proceeding commands will be entered into the opened window1.
+
+3. Create and activate a virtual environment called 'bimana-env' in your desired directory:
+
+ ```pip install --upgrade pip```
+
+ ```python -m venv bimana-env```
+
+ ```. bimana-env/bin/activate``` (*Linux* and *macOS* users) or ```bimana-env\Scripts\activate.bat``` (*Windows* users)
+
+4. Install PyTorch by specifying your system configuration using the official [PyTorch get started tool](https://pytorch.org/get-started/locally/) and running the generated command:
+
+
+
+ For example, according to the image above, Windows users without a GPU (i.e. CPU only) will run:
+
+ ```pip3 install torch torchvision torchaudio```
+
+
+5. Clone this repository into your desired directory:
+
+ ```
+ git lfs install
+ git clone https://github.com/AlphonsG/BIMANA.git
+ ```
+
+6. Navigate into the cloned directory:
+
+ ```cd BIMANA```
+
+7. Install Bimana:
+
+ ```
+ git submodule update --init --recursive
+ pip install -e .
+ ```
+
+Notes:
+ - 1Confirm that the correct python version for Bimana has been installed using the `python -V` command in the terminal. If this command does not report the correct python version, try using the `python3 -v` command instead. If the second command produces the expected result, replace all `python` and `pip` commands in this guide with `python3` and `pip3`, respectively.
+
+ - The virtual environment can be deactivated using:
+
+ ```deactivate```
+
+## Usage
+
+Enter `bimana -h` or `bimana --help` within the `bimana-env` environment after installation for details on how to use Bimana.
+
+Example commands that can be used to test Bimana using input data provided in
+each folder [here](misc/examples) are given below. After
+processing is finished for a given folder containing input images, multiple subfolders
+containing generated outputs (e.g. images, CSV files, etc) are created. Examples of these are also provided.
+
+Example commands (first run `cd misc` from the cloned repository folder):
+
+- Histological Section Analysis
+ ```
+ bimana histological-section-analysis --staining-amount-in-tissue-area --cilia-amount-above-tissue-area
+ ```
+
+- Tight junction analysis
+ ```
+ bimana tight-junction-analysis misc/examples/tight_junctions --analyse-tight-junctions --analyse-cells
+ ```
+- Live cell imaging metrics analysis
+ ```
+ bimana live-cell-imaging metrics-file-processing misc/examples/live_cell_imaging
+ ```
+
+## License
+
+[MIT License](LICENSE)
+
+
+## Community guidelines
+
+ Guidelines for third-parties wishing to:
+
+- Contribute to the software
+- Report issues or problems with the software
+- Seek support
+
+can be found [here](CONTRIBUTING.md).
+
+## Acknowledgements
+
+- https://github.com/xavysp/DexiNed
+- https://github.com/DevonsMo/IJOQ
diff --git a/bimana/__init__.py b/bimana/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bimana/__main__.py b/bimana/__main__.py
new file mode 100644
index 0000000..86b88f6
--- /dev/null
+++ b/bimana/__main__.py
@@ -0,0 +1,11 @@
+from bimana.cli import cli
+
+
+def main() -> int:
+ cli()
+
+ return 0
+
+
+if __name__ == '__main__':
+ main()
diff --git a/bimana/cli.py b/bimana/cli.py
new file mode 100644
index 0000000..2228a89
--- /dev/null
+++ b/bimana/cli.py
@@ -0,0 +1,21 @@
+import click
+
+from bimana.histological_section.commands import histological_section_analysis
+from bimana.tight_junctions.commands import tight_junction_analysis
+from bimana.live_cell_imaging.commands import live_cell_imaging
+
+CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
+
+
+@click.group(context_settings=CONTEXT_SETTINGS)
+def cli() -> None:
+ """ Simple command line utility called `bimana`.
+
+ The cli is composed of commands for performing automated bio-image
+ analysis tasks.
+ """
+
+
+cli.add_command(histological_section_analysis)
+cli.add_command(tight_junction_analysis)
+cli.add_command(live_cell_imaging)
diff --git a/bimana/histological_section/__init__.py b/bimana/histological_section/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bimana/histological_section/analysis.py b/bimana/histological_section/analysis.py
new file mode 100644
index 0000000..046e7ee
--- /dev/null
+++ b/bimana/histological_section/analysis.py
@@ -0,0 +1,254 @@
+from pathlib import Path
+from typing import Any
+
+import numpy as np
+import numpy.typing as npt
+from bimana.utils.file_processing import crop_and_save_images, load_imgs
+from bimana.utils.image_processing import (binary_to_bgr_image,
+ bound_foreground,
+ bounded_foreground_polyline,
+ draw_polyline, largest_objects,
+ remove_isolated_segmented_objects,
+ segment_image,
+ segment_polyline_bounded_region,
+ segment_region_above_polyline,
+ segment_region_within_image,
+ smooth_foreground_bounds,
+ subimage_coordinates)
+from bimana.utils.quantification import percentage_foreground_in_region
+
+BIN_IMG_KEY = 'binary_image'
+BIN_IMG_NO_ISO_KEY = 'binary_image_without_isolated_non_tissue'
+POLYLINE_KEY = 'raw_tissue_boundary'
+SMOOTHED_POLYLINE_KEY = 'smoothed_tissue_boundary'
+POLYLINE_ORI_KEY = 'tissue_boundary_on_original'
+SEGD_FG_IN_RGN_KEY = 'staining_within_tissue_boundary'
+SEGD_FG_ABOVE_RGN_KEY = 'cilia_above_tissue_area'
+SEGD_FG_ABOVE_RGN_ORI_KEY = 'cilia_region_on_original'
+FIN_BIN_IMG_KEY = 'segmented_tissue'
+
+
+def tissue_boundary(
+ img: npt.NDArray[Any],
+ non_tissue_lower_bgr: npt.NDArray[np.int_],
+ non_tissue_upper_bgr: npt.NDArray[np.int_],
+ selected_tissue: str = 'all',
+ top: int | None = None,
+ minimum: int | None = None,
+ iso_non_tissue_sens: float | None = 0.2,
+ smooth_segmented_tissue_boundary: bool = True,
+) -> tuple[tuple[list[list[npt.NDArray[Any]]], list[list[npt.NDArray[Any]]]],
+ list[tuple[str, npt.NDArray[np.uint8]]]]:
+ """Determines the tissue boundary in an image of a histological section.
+
+ Args:
+ img: A colour histological section image.
+ non_tissue_lower_bgr: The lower bound of BGR pixel values (all between
+ 0 and 255) corresponding to non-tissue that will be segmented out.
+ non_tissue_upper_bgr: The upper bound of BGR pixel values (all between
+ 0 and 255) corresponding to non-tissue that will be segmented out.
+ selected_tissue: What to treat as tissue after binarizing the image -
+ if set to all, creates a bounding polyline around all foreground
+ pixels in the image and treats the inner area as tissue; if set to
+ largest, treats only the largest group(s) of connected foreground
+ pixels (objects) in the image as tissue.
+ top: The number of top largest objects in the image to treat as
+ tissue, when the selected_tissue argument is set to 'largest'.
+ minimum: The minimum area, in pixels, for objects in the image to be
+ treated as tissue, when the selected_tissue argument is set to
+ 'largest'.
+ iso_non_tissue_sens: The sensitivity, between 0 and 1, of the algorithm
+ that identifies tissue to isolated non-tissue objects. Larger
+ values reduce the strictness of the criteria objects must meet to
+ be classified as isolated and thus ignored as non-tissue objects.
+ If None, will not attempt to detect and ignore isolated non-tissue
+ objects.
+ smooth_segmented_tissue_boundary: If True, smooths the generated
+ boundary of the tissue area.
+
+ Returns:
+ A sequence of x-coordinates for the upper tissue boundary(s) across the
+ width of the image and the corresponding y-coordinates of lower tissue
+ boundary(s) across the image. Also returns a sequence of the
+ intermediate images generated during processing.
+ """
+ procd_imgs = []
+
+ # segment image
+ bin_img = ~segment_image(img, non_tissue_lower_bgr, non_tissue_upper_bgr)
+ bgr_img = binary_to_bgr_image(bin_img)
+ procd_imgs.append((BIN_IMG_KEY, bgr_img))
+
+ if iso_non_tissue_sens is not None:
+ bin_img = remove_isolated_segmented_objects(
+ bin_img, iso_non_tissue_sens)
+ bgr_img = binary_to_bgr_image(bin_img)
+ procd_imgs.append((BIN_IMG_NO_ISO_KEY, bgr_img))
+
+ # determine tissue boundary
+ upper_lower_xs, upper_lower_ys = largest_objects(bin_img, minimum, top) \
+ if selected_tissue == 'largest' else bound_foreground(bin_img)
+
+ if not isinstance(upper_lower_xs[0], list):
+ upper_lower_xs, upper_lower_ys = [upper_lower_xs], [upper_lower_ys]
+
+ tiss_img = np.zeros(bin_img.shape, bool)
+ polylines = []
+ for i, (ul_xs, ul_ys) in enumerate(zip(upper_lower_xs, upper_lower_ys)):
+ polyline = bounded_foreground_polyline(ul_xs, ul_ys)
+ tiss_img |= segment_polyline_bounded_region(polyline, bin_img.shape)
+ polylines.append(polyline)
+
+ bgr_img = binary_to_bgr_image(tiss_img)
+ procd_imgs.append((FIN_BIN_IMG_KEY, bgr_img))
+ smd_polyline_img = polyline_img = bgr_img
+
+ for i, (ul_xs, ul_ys) in enumerate(zip(upper_lower_xs, upper_lower_ys)):
+ polyline = polylines[i]
+ polyline_img = draw_polyline(polyline_img, polyline)
+
+ if smooth_segmented_tissue_boundary:
+ ul_xs, ul_ys = smooth_foreground_bounds(bin_img, ul_xs, ul_ys)
+ polyline = bounded_foreground_polyline(ul_xs, ul_ys)
+ smd_polyline_img = draw_polyline(smd_polyline_img, polyline)
+ upper_lower_xs[i], upper_lower_ys[i] = ul_xs, ul_ys
+
+ img = draw_polyline(img, polyline)
+
+ procd_imgs.append((POLYLINE_KEY, polyline_img))
+ procd_imgs.append((POLYLINE_ORI_KEY, img))
+ if smooth_segmented_tissue_boundary:
+ procd_imgs.append((SMOOTHED_POLYLINE_KEY, smd_polyline_img))
+
+ return (upper_lower_xs, upper_lower_ys), procd_imgs
+
+
+def amount_staining_in_tissue_area(
+ img: npt.NDArray[Any],
+ upper_lower_xs: list[list[npt.NDArray[Any]]],
+ upper_lower_ys: list[list[npt.NDArray[Any]]],
+ stain_lower_bgr: npt.NDArray[np.int_],
+ stain_upper_bgr: npt.NDArray[np.int_],
+) -> tuple[float, int, int, list[tuple[str, npt.NDArray[np.uint8]]]]:
+ """Finds how much of a histological section image's tissue area is stained.
+
+ Args:
+ img: A colour histological section image.
+ upper_lower_xs: A sequence of the x-coordinates of the upper and lower
+ tissue boundary(s) across the image.
+ upper_lower_ys: A sequence of the y-coordinates of the upper and lower
+ tissue boundary(s) across the image.
+ stain_lower_bgr: The lower bound of BGR pixel values (all between
+ 0 and 255) corresponding to staining.
+ stain_upper_bgr: The upper bound of BGR pixel values (all between
+ 0 and 255) corresponding to staining.
+
+ Returns:
+ The percentage of a histological section image's tissue area that is
+ stained, along with the corresponding amount of staining and size of
+ the tissue area (in pixels), followed by a sequence of the intermediate
+ images generated during processing.
+ """
+ # calculate percentage of staining in tissue region
+ tissue_mask = np.zeros(img.shape[:2], bool)
+ procd_img = img.copy()
+ polylines = []
+ for ul_xs, ul_ys in zip(upper_lower_xs, upper_lower_ys):
+ polyline = bounded_foreground_polyline(ul_xs, ul_ys)
+ tissue_mask = tissue_mask | segment_polyline_bounded_region(
+ polyline, img.shape[:2])
+ polylines.append(polyline)
+
+ stain_mask = segment_region_within_image(img, stain_lower_bgr,
+ stain_upper_bgr, tissue_mask)
+ pct_stain, stain_amt, tiss_size = percentage_foreground_in_region(
+ stain_mask, tissue_mask)
+
+ procd_img[~stain_mask] = (0, 0, 0)
+ for polyline in polylines:
+ procd_img = draw_polyline(procd_img, polyline)
+
+ return pct_stain, stain_amt, tiss_size, [(SEGD_FG_IN_RGN_KEY, procd_img)]
+
+
+def amount_cilia_above_tissue_area(
+ img: npt.NDArray[Any],
+ upper_lower_xs: list[list[npt.NDArray[Any]]],
+ upper_lower_ys: list[list[npt.NDArray[Any]]],
+ cilia_lower_bgr: npt.NDArray[np.int_],
+ cilia_upper_bgr: npt.NDArray[np.int_],
+ thickness: int,
+) -> tuple[float, int, int, list[tuple[str, npt.NDArray[np.uint8]]]]:
+ """Finds amount of cilia above a histological section image's tissue area.
+
+ Args:
+ img: A colour histological section image.
+ upper_xs: A sequence of the x-coordinates of the upper and lower tissue
+ boundary(s) across the image.
+ upper_ys: A sequence of the y-coordinates of the upper and lower tissue
+ boundary(s) across the image.
+ cilia_lower_bgr: The lower bound of BGR pixel values (all between
+ 0 and 255) corresponding to cilia.
+ cilia_upper_bgr: The upper bound of BGR pixel values (all between
+ 0 and 255) corresponding to corresponding to cilia.
+ thickness: The expected vertical thickness, in pixels, of the
+ cilia-containing region above the tissue area.
+
+ Returns:
+ The percentage of the region above the tissue area of an image of a
+ histological section that is occupied by cilia, along with the
+ corresponding amount of cilia and size of the cilia-containing region
+ (in pixels), followed by a sequence of the intermediate images
+ generated during processing.
+ """
+ # calculate percentage of cilia above tissue region
+ cilia_region_mask = np.zeros(img.shape[:2], bool)
+ procd_img = img.copy()
+ polylines = []
+ for ul_xs, ul_ys in zip(upper_lower_xs, upper_lower_ys):
+ polyline = np.array([[x, y] for x, y in zip(ul_xs[0], ul_ys[0])])
+ mask = segment_region_above_polyline(
+ polyline, thickness, img.shape[:2])
+ cilia_region_mask |= mask
+
+ reg_coords_xs, reg_coords_ys = largest_objects(mask)
+ for rc_xs, rc_ys in zip(reg_coords_xs, reg_coords_ys):
+ polyline = bounded_foreground_polyline(rc_xs, rc_ys)
+ polylines.append(polyline)
+
+ cilia_mask = segment_region_within_image(
+ img, cilia_lower_bgr, cilia_upper_bgr, cilia_region_mask)
+ pct_cilia, cilia_amt, reg_size = percentage_foreground_in_region(
+ cilia_mask, cilia_region_mask)
+
+ procd_img[~cilia_mask] = (0, 0, 0)
+
+ for polyline in polylines:
+ procd_img = draw_polyline(procd_img, polyline)
+
+ return pct_cilia, cilia_amt, reg_size, [(SEGD_FG_ABOVE_RGN_KEY, procd_img)]
+
+
+def crop_and_save_tissue_sections(
+ input_dir: Path,
+ shrink_factor: int | None = 1000,
+) -> list[Path]:
+ """Crops and saves tissue sections from images in the input directory.
+
+ Args:
+ input_dir: The input directory.
+ shrink_factor: Factor to shrink images by before loading them into
+ memory.
+
+ Returns:
+ The directories containing the saved tissue sections. Each directory
+ contains one tissue section image.
+ """
+ imgs = load_imgs(input_dir, shrink_factor)
+ output_paths = []
+ for f, img in imgs:
+ tissue_section_coords = subimage_coordinates(img)
+ tissue_section_coords *= shrink_factor
+ output_paths += crop_and_save_images(f, tissue_section_coords, True)
+
+ return output_paths
diff --git a/bimana/histological_section/commands.py b/bimana/histological_section/commands.py
new file mode 100644
index 0000000..1db4f89
--- /dev/null
+++ b/bimana/histological_section/commands.py
@@ -0,0 +1,266 @@
+from collections import defaultdict
+from pathlib import Path
+
+import click
+
+from bimana.histological_section.analysis import (
+ amount_cilia_above_tissue_area, amount_staining_in_tissue_area,
+ crop_and_save_tissue_sections, tissue_boundary)
+from bimana.utils.commands import parse_input_bgr
+from bimana.utils.file_processing import (DirFormat, get_dirs, load_imgs,
+ save_csv, save_imgs)
+from bimana.utils.image_processing import scale_bgr_values
+
+DIR_FORMAT = DirFormat(1).name
+NON_TISSUE_LOWER_BGR = ('210', '210', '210')
+NON_TISSUE_UPPER_BGR = ('255', '255', '255')
+STAIN_LOWER_BGR = ('0', '0', '0')
+STAIN_UPPER_BGR = ('255', '255', '150')
+CILIA_LOWER_BGR = ('220', '220', '220')
+CILIA_UPPER_BGR = ('245', '245', '245')
+ISO_NON_TISSUE_SENS = 0.08
+NO_SMOOTH_SEGMENTED_TISSUE_BOUNDARY = False
+CILIA_REGION_THICKNESS = 15
+DONT_SAVE_PROCD_IMGS = False
+MULTI_SECTION_IMAGES = False
+IMAGE_SHRINK_FACTOR = None
+DONT_FILTER_ISO_NON_TISSUE = False
+
+METRICS_CSV_FILENAME = 'metrics.csv'
+
+
+@click.command()
+@click.argument('root_directory', type=click.Path(
+ exists=True, file_okay=False))
+@click.option('--staining-amount-in-tissue-area', is_flag=True,
+ help='Calculate how much of a histological section image\'s '
+ 'tissue area is stained.')
+@click.option('--cilia-amount-above-tissue-area', is_flag=True,
+ help='Calculate the amount of cilia above a histological '
+ 'section image\'s tissue area.')
+@click.option('--selected-tissue', type=click.Choice(['all', 'largest'],
+ case_sensitive=False), default='all', show_default=True,
+ help='What to treat as tissue after binarizing the '
+ 'image - if set to all, creates a bounding polyline around all '
+ 'foreground pixels in the image and treats the inner area as '
+ 'tissue; if set to largest, treats only the largest group(s) of '
+ 'connected foreground pixels (objects) in the image as tissue.')
+@click.option('--top', type=click.IntRange(1),
+ help='The number of top largest objects in the image to treat '
+ 'as tissue, when \'largest\' is chosen for the '
+ '--selected-tissue option.')
+@click.option('--minimum', type=click.IntRange(0),
+ help='The minimum area, in pixels, for objects in the image to '
+ 'treat as tissue, when \'largest\' is chosen for the '
+ '--selected-tissue option.')
+@click.option('--directory-format', type=click.Choice([DirFormat(1).name,
+ DirFormat(2).name, DirFormat(3).name], case_sensitive=False),
+ default=DIR_FORMAT, show_default=True,
+ help='Location of image files to process in the root directory '
+ f'tree - if set to {DirFormat(1).name}, processes images '
+ f'in the root directory; if set to {DirFormat(2).name}, '
+ 'processes images in subdirectories of the root directory; '
+ f'if set to {DirFormat(3).name}, processes images '
+ 'in all directories of the root directory tree.')
+@click.option('--non-tissue-lower-colour-limit', nargs=3,
+ default=NON_TISSUE_LOWER_BGR, show_default=True,
+ help='Control the region of the image identified as tissue - '
+ 'pixels in the image with blue, green and red intensity values '
+ 'greater than the provided values will be considered '
+ 'non-tissue.')
+@click.option('--non-tissue-upper-colour-limit', nargs=3,
+ default=NON_TISSUE_UPPER_BGR, show_default=True,
+ help='Control the region of the image identified as tissue - '
+ 'pixels in the image with blue, green and red intensity values '
+ 'lesser than the provided values will be considered non-tissue.')
+@click.option('--staining-lower-colour-limit', nargs=3,
+ default=STAIN_LOWER_BGR, show_default=True,
+ help='Control the colour of the staining to identify in the '
+ 'image - pixels in the image with blue, green and red intensity '
+ 'values greater than the provided values will be considered '
+ 'staining.')
+@click.option('--staining-upper-colour-limit', nargs=3,
+ default=STAIN_UPPER_BGR, show_default=True,
+ help='Control the colour of the staining to identify in the '
+ 'image - pixels in the image with blue, green and red intensity '
+ 'values lesser than the provided values will be considered '
+ 'staining.')
+@click.option('--cilia-lower-colour-limit', nargs=3,
+ default=CILIA_LOWER_BGR, show_default=True,
+ help='Control the colour of the cilia to identify in the '
+ 'image - pixels in the image with blue, green and red intensity '
+ 'values greater than the provided values will be considered '
+ 'cilia.')
+@click.option('--cilia-upper-colour-limit', nargs=3, default=CILIA_UPPER_BGR,
+ show_default=True,
+ help='Control the colour of the cilia to identify in the '
+ 'image - pixels in the image with blue, green and red intensity '
+ 'values lesser than the provided values will be considered '
+ 'cilia.')
+@click.option('--no-isolated-non-tissue-filtering', is_flag=True,
+ default=DONT_FILTER_ISO_NON_TISSUE, show_default=True,
+ help='Do not filter out isolated objects identified in the '
+ 'image as non-tissue.')
+@click.option('--sensitivity-to-isolated-non-tissue',
+ type=click.FloatRange(0, 1), default=ISO_NON_TISSUE_SENS,
+ show_default=True,
+ help='Filter out more isolated objects identified in the image '
+ 'as non-tissue with greater sensitivity values.')
+@click.option('--no-tissue-boundary-smoothing', is_flag=True,
+ default=NO_SMOOTH_SEGMENTED_TISSUE_BOUNDARY, show_default=True,
+ help='Do not smooth the identified tissue boundary as a post '
+ 'processing step.')
+@click.option('--cilia-region-thickness', type=click.IntRange(1),
+ default=CILIA_REGION_THICKNESS, show_default=True,
+ help='Vertical thickness, in pixels, of the cilia-containing '
+ 'region above the tissue area.')
+@click.option('--no-image-processing-visualization', is_flag=True,
+ help='Do not save image files visualizing different stages of '
+ 'image processing.')
+@click.option('--multi-section-images', is_flag=True,
+ help='Treat input images as large images containing multiple '
+ 'tissue sections - will crop and save individual tissue '
+ 'sections as separate files, then analyse.')
+@click.option('--image-shrink-factor', type=click.IntRange(1, min_open=True),
+ help='Factor to shrink images by before loading into memory.')
+def histological_section_analysis(
+ root_directory: str | Path,
+ staining_amount_in_tissue_area: bool,
+ cilia_amount_above_tissue_area: bool,
+ selected_tissue: str = 'all',
+ top: int | None = None,
+ minimum: int | None = None,
+ directory_format: str = DIR_FORMAT,
+ non_tissue_lower_colour_limit: tuple[str, str, str] = NON_TISSUE_LOWER_BGR,
+ non_tissue_upper_colour_limit: tuple[str, str, str] = NON_TISSUE_UPPER_BGR,
+ staining_lower_colour_limit: tuple[str, str, str] = STAIN_LOWER_BGR,
+ staining_upper_colour_limit: tuple[str, str, str] = STAIN_UPPER_BGR,
+ cilia_lower_colour_limit: tuple[str, str, str] = CILIA_LOWER_BGR,
+ cilia_upper_colour_limit: tuple[str, str, str] = CILIA_UPPER_BGR,
+ no_isolated_non_tissue_filtering: bool = DONT_FILTER_ISO_NON_TISSUE,
+ sensitivity_to_isolated_non_tissue: float = ISO_NON_TISSUE_SENS,
+ no_tissue_boundary_smoothing: bool = NO_SMOOTH_SEGMENTED_TISSUE_BOUNDARY,
+ cilia_region_thickness: int = CILIA_REGION_THICKNESS,
+ no_image_processing_visualization: bool = DONT_SAVE_PROCD_IMGS,
+ multi_section_images: bool = MULTI_SECTION_IMAGES,
+ image_shrink_factor: int | None = IMAGE_SHRINK_FACTOR,
+) -> None:
+ """Analyse histological section images.
+
+ Analysis consists of calculating how much of a histological section image's
+ tissue area is stained as a percentage and/or the amount of cilia in the
+ region above a histological section image's tissue area as a percentage.
+ Saves generated data in the root directory tree.
+
+ ROOT_DIRECTORY:
+
+ The directory to search for images to process in. When using the web
+ interface, directory must be zipped.
+
+
+ IMPORTANT NOTES
+
+ Colour limit options:
+
+ Options containing the term '...-colour-limit' accept 3 input values. The
+ first, second and third input value is a blue, green and red pixel
+ intensity value, respectively. Each intensity value can be either a whole
+ number between 0 and 255 (raw pixel value) or a decimal number from 0.0 to
+ 1.0 (representing 0% to 100% intensity) which will be converted to a raw
+ pixel value internally. Each pixel in any given colour image is composed of
+ blue, green and red intensity values which result in the observable colour
+ of the pixel, such as bright yellow. Specific details on what the inputs to
+ each '...-colour-limit' option affect is provided in the corresponding help
+ message.
+
+ Default option values:
+
+ The default option values were fine tuned for processing histological
+ sections of epithelium with alcian blue stain (a mucus stain), for example,
+ https://github.com/AlphonsG/BIMANA
+ """
+ # check inputs
+ if not (staining_amount_in_tissue_area or cilia_amount_above_tissue_area):
+ click.echo('Invalid inputs: --staining-amount-in-tissue-area and/or '
+ '--cilia-amount-above-tissue-area option(s) must be '
+ 'selected.')
+ return
+
+ try:
+ non_tissue_lower_bgr = parse_input_bgr(non_tissue_lower_colour_limit)
+ non_tissue_upper_bgr = parse_input_bgr(non_tissue_upper_colour_limit)
+ stain_lower_bgr = parse_input_bgr(staining_lower_colour_limit)
+ stain_upper_bgr = parse_input_bgr(staining_upper_colour_limit)
+ cilia_lower_bgr = parse_input_bgr(cilia_lower_colour_limit)
+ cilia_upper_bgr = parse_input_bgr(cilia_upper_colour_limit)
+ except ValueError:
+ click.echo('Invalid value provided for \'...--colour-limit\' '
+ 'option(s).')
+ return
+
+ non_tiss_sens = (not no_isolated_non_tissue_filtering and
+ sensitivity_to_isolated_non_tissue) or None
+
+ root_dir = output_dir = Path(root_directory)
+ output_dirs = []
+ metrics = defaultdict(list)
+ input_dirs = get_dirs(root_dir, DirFormat[directory_format])
+
+ if multi_section_images:
+ orig_input_dirs = input_dirs.copy()
+ input_dirs = []
+ for input_dir in orig_input_dirs:
+ input_dirs += crop_and_save_tissue_sections(input_dir)
+
+ for curr_dir in input_dirs:
+ if curr_dir in output_dirs: # previously generated output directory
+ continue
+ for f, img in load_imgs(curr_dir, image_shrink_factor):
+ curr_output_dir = output_dir / curr_dir.relative_to(
+ root_dir) / f'{f.stem}_{f.suffix[1:]}'
+ output_dirs.append(curr_output_dir)
+ metrics['Image'].append(f.name)
+ metrics['File path'].append(str(f))
+
+ procd_imgs = []
+
+ upper_lower_xs_ys, curr_procd_imgs = tissue_boundary(
+ img, scale_bgr_values(non_tissue_lower_bgr),
+ scale_bgr_values(non_tissue_upper_bgr), selected_tissue,
+ top, minimum, non_tiss_sens,
+ not no_tissue_boundary_smoothing)
+ procd_imgs += curr_procd_imgs
+
+ if staining_amount_in_tissue_area:
+ results = amount_staining_in_tissue_area(
+ img, upper_lower_xs_ys[0], upper_lower_xs_ys[1],
+ scale_bgr_values(stain_lower_bgr),
+ scale_bgr_values(stain_upper_bgr))
+ pct_stain, stain_amt, tiss_size, curr_procd_imgs = results
+ procd_imgs += curr_procd_imgs
+
+ metrics['Amount of staining (no. pixels)'].append(stain_amt)
+ metrics['Tissue area size (no. pixels)'].append(tiss_size)
+ metrics['Percentage of staining in tissue area (%)'].append(
+ pct_stain)
+
+ if cilia_amount_above_tissue_area:
+ results = amount_cilia_above_tissue_area(
+ img, upper_lower_xs_ys[0], upper_lower_xs_ys[1],
+ scale_bgr_values(cilia_lower_bgr),
+ scale_bgr_values(cilia_upper_bgr), cilia_region_thickness)
+ pct_cilia, cilia_amt, reg_size, curr_procd_imgs = results
+ procd_imgs += curr_procd_imgs
+
+ metrics['Amount of cilia (no. pixels)'].append(cilia_amt)
+ metrics['Cilia-containing region size (no. pixels)'].append(
+ reg_size)
+ metrics['Percentage of region occupied by cilia (%)'].append(
+ pct_cilia)
+
+ if not no_image_processing_visualization:
+ curr_output_dir.mkdir(parents=True, exist_ok=True)
+ save_imgs(procd_imgs, curr_output_dir)
+
+ # save metrics
+ save_csv(metrics, output_dir / METRICS_CSV_FILENAME)
diff --git a/bimana/live_cell_imaging/__init__.py b/bimana/live_cell_imaging/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bimana/live_cell_imaging/commands.py b/bimana/live_cell_imaging/commands.py
new file mode 100644
index 0000000..cb1e074
--- /dev/null
+++ b/bimana/live_cell_imaging/commands.py
@@ -0,0 +1,11 @@
+import click
+from bimana.live_cell_imaging.metrics_file_processing import (
+ metrics_file_processing)
+
+
+@click.group(help='Process live cell imaging data.')
+def live_cell_imaging() -> None:
+ pass
+
+
+live_cell_imaging.add_command(metrics_file_processing)
diff --git a/bimana/live_cell_imaging/metrics_file_processing.py b/bimana/live_cell_imaging/metrics_file_processing.py
new file mode 100644
index 0000000..87a74de
--- /dev/null
+++ b/bimana/live_cell_imaging/metrics_file_processing.py
@@ -0,0 +1,604 @@
+import os
+import re
+from collections import defaultdict
+from pathlib import Path
+from statistics import mean, stdev
+from typing import Any
+
+import click
+import matplotlib.pyplot as plt
+import numpy as np
+import numpy.typing as npt
+import pandas as pd
+from matplotlib.ticker import MultipleLocator
+
+MEAN_COL, STD_COL, SEM_COL = 'Average', 'StDev', 'SEM'
+VEHICLE_CONTROL = 'DMSO 0.05%'
+POSITIVE_CONTROL = 'Pos 10 µM'
+NEGATIVE_CONTROL = 'UT 100%'
+PLACEHOLDER_COMPOUNDS = 'CA CB CC CD'
+DO_NOT_USE_NOTES_COMPOUNDS = False
+DO_NOT_GENERATE_FIGURES = False
+FIGURE_TIMEPOINTS = '6 12 24'
+FIGURE_METRIC_THRESHOLD = 120
+
+
+class MetricsTxtFileProcessor:
+ """Processes raw .txt files containing live cell imaging metrics.
+
+ The .txt files are those generated by Incuctye Software from a live cell
+ imaging experiment, such as airway epithelium wound closure experiments
+ utilizing, for example, IncuCyte® ImageLock 96-well plates, IncuCyte®
+ ZOOM, etc, and, for example, various drug compounds, such as DMSO for
+ control, etc. From these input files, generates data such as image figures
+ and excel spreed sheets for analysis.
+
+ Attributes:
+ txt_file: The path to the input .txt file.
+ metrics_df: A data frame containing the metrics.
+ info_df: A data frame containing the experiment information.
+ time_df: A data frame containing the time data.
+ stats_df: A data frame containing the metrics and computed statistics.
+ ctrl_df: A data frame with the metrics for the control compound.
+ dfs: A dictionary of the split data frames, with keys of the compounds
+ and concentrations per compound.
+ fld_chg_df: A data frame containing the metrics in terms of fold
+ changes.
+ fld_chg_stats_df: A data frame containing the metrics and computed
+ statistics in terms of fold changes.
+ """
+
+ def __init__(self, txt_file: Path) -> None:
+ """Inits MetricsTxtFileProcessor with the .txt file path.
+
+ Args:
+ txt_file: The path to the input .txt file.
+ """
+ self.txt_file = txt_file
+ self.stats_df = None
+
+ def _plot_summary(
+ self,
+ df: pd.DataFrame,
+ ax: plt.Axes,
+ metric_threshold: int | None = None,
+ ) -> None:
+ x = [mean(df[c]) for c in df]
+ y = [i for i in range(1, len(df.columns) + 1)]
+ e = [stdev(df[c]) for c in df]
+
+ ax.errorbar(x, y, xerr=e, linestyle='None', marker='|', color='k',
+ capsize=3.5, markersize=15)
+ ax.set_ylim(0, len(df.columns) + 1)
+ ax.set(yticks=[i for i in range(1, len(df.columns) + 1)],
+ yticklabels=[f'{c}h' for c in df.columns])
+
+ colour = np.random.rand(3,)
+ for col in df:
+ x = list(df[col])
+ y = [list(df.columns).index(col) + 1] * len(x)
+ ax.plot(x, y, c=colour, marker='o', linestyle='None',
+ markeredgecolor='k')
+
+ if metric_threshold is not None:
+ ax.vlines(metric_threshold, 0, len(df.columns) + 1, linewidth=1,
+ linestyles='dashed')
+
+ ax.xaxis.set_major_locator(MultipleLocator(100))
+ ax.xaxis.set_minor_locator(MultipleLocator(50))
+ ax.set_xlim(0, 300)
+
+ def _flag(self, x: npt.ArrayLike) -> npt.NDArray[Any]:
+
+ return np.where(x > 25, 'background-color: red;text-align: center',
+ None)
+
+ def _comp_col_wdhs(self, df: pd.DataFrame) -> list[int]:
+ col_wdhs = []
+ for i in range(0, len(df.columns)):
+ for x in df.iloc[:, i]:
+ try:
+ val_len = len(str(round(x, 8)))
+ except TypeError:
+ val_len = len(str(x))
+ col_wdhs.append(max([val_len, len(df.columns[i])]))
+
+ col_wdhs = [x if x != 0 else col_wdhs[i - 1] for i, x in
+ enumerate(col_wdhs)]
+
+ return col_wdhs
+
+ def _get_compounds_and_concentrations(self, df: pd.DataFrame) -> list[str]:
+ compds_concs = [well.rsplit(' ', 1)[0] for well in df.columns if
+ well != '']
+ compds_concs = list(dict.fromkeys(compds_concs).keys())
+
+ return compds_concs
+
+ def process(
+ self,
+ use_notes_compounds: bool,
+ placeholder_compounds: list[str],
+ vehicle_control: str,
+ fig_tpts: list[int],
+ ) -> None:
+ """Processes raw .txt by generating corresponding data frames.
+
+ Args:
+ use_notes_compounds: Replace placeholder compound names in the main
+ header with compound names listed in the 'Notes' of the input
+ text file.
+ placeholder_compounds: The placeholder compound names (to be
+ replaced with names from the 'Notes' section) in the main
+ header of input text files.
+ vehicle_control: The vehicle control used in the experiment.
+ fig_tpts: The key experiment time points (in hours).
+ """
+ self.metrics_df, self.info_df, self.time_df = self.create_dataframes()
+ if use_notes_compounds:
+ self.metrics_df = self.use_notes_compounds(
+ self.metrics_df, self.info_df, placeholder_compounds)
+
+ self.stats_df = self.compute_stats(self.metrics_df)
+ self.ctrl_df = self.get_compound_dataframe(self.stats_df,
+ vehicle_control)
+ self.fld_chg_df = self.compute_fold_changes(self.metrics_df,
+ self.ctrl_df)
+ self.fld_chg_stats_df = self.compute_stats(self.fld_chg_df)
+ self.compds_df = self.get_timepoints_dataframe(
+ self.fld_chg_df, self.time_df, fig_tpts)
+ self.dfs = self.split_dataframe(self.compds_df)
+
+ def create_dataframes(
+ self,
+ ) -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
+ """Creates data frames from the input .txt file.
+
+ Returns:
+ A data frame containing the metrics, a data frame containing the
+ time data, and a data frame containing the experiment information.
+ """
+ with open(self.txt_file, encoding='utf-8') as f:
+ num_cols = max(len(line.split('\t')) for line in f)
+ f.seek(0)
+ df = pd.read_csv(f, names=range(num_cols), delimiter='\t',
+ header=None)
+
+ if df.loc[6, 0] is not np.nan:
+ df.loc[5.5] = [np.nan] * num_cols
+ df = df.sort_index().reset_index(drop=True)
+
+ df.columns = df[7:8].values.tolist()[0]
+ info_df, df = df.iloc[0:6, 0].copy(), df[8::]
+ info_df = info_df.to_frame()
+ info_df.columns = np.arange(1)
+ df = df.replace(r'^\s*$', np.nan, regex=True)
+ df = pd.concat([df.iloc[:, 0], df.iloc[:, 1::].apply(pd.to_numeric)],
+ axis=1)
+
+ time_df, df = df.iloc[:, 0:2].copy(), df.iloc[:, 2::]
+ prev_compd = df.columns[0].rsplit(' ', 1)[0]
+ if ' ' not in df.columns[0]:
+ prev_compd = re.findall(r'\d+', df.columns[0])[-1]
+
+ df.insert(len(df.columns), '', '', True)
+ offset = 0
+ for i, well in enumerate(df.iloc[:, 0:-1]):
+ if ((' ' in well and (curr_compd := well.rsplit(
+ ' ', 1)[0]) != prev_compd) or (' ' not in well and (
+ curr_compd := re.findall(
+ r'\d+', well)[-1]) != prev_compd)):
+ df.insert(i + offset, '', '', True)
+ offset += 1
+ prev_compd = curr_compd
+
+ return df, info_df, time_df
+
+ def compute_stats(self, metrics_df: pd.DataFrame) -> pd.DataFrame:
+ """Computes the statistics of a metrics data frame.
+
+ Statistics consist of the mean, standard deviation and standard error
+ of the mean across adjacent rows in the data frame, added as new
+ columns.
+
+ Args:
+ metrics_df: The metrics data frame.
+
+ Returns:
+ The metrics data frame with computed statistics.
+ """
+ stats_df = metrics_df.copy()
+ metrics = defaultdict(list)
+ offset = 0
+ for i, well in enumerate(metrics_df):
+ if well == '':
+ means = [mean(ms) for ms in metrics.values()]
+ stds = [stdev(ms) for ms in metrics.values()]
+ sems = [stds[i] / means[i] * 100 if means[i] != 0 else 0 for i
+ in range(0, len(metrics))]
+ stats_df.insert(i + offset, MEAN_COL, means, True)
+ stats_df.insert(i + 1 + offset, STD_COL, stds, True)
+ stats_df.insert(i + 2 + offset, SEM_COL, sems, True)
+ offset += 3
+ metrics = defaultdict(list)
+ else:
+ for i, m in enumerate(metrics_df[well]):
+ if not np.isnan(m):
+ metrics[i].append(m)
+
+ return stats_df
+
+ def get_compound_dataframe(
+ self,
+ metrics_df: pd.DataFrame,
+ compd: str,
+ ) -> pd.DataFrame | None:
+ """Gets the metrics data frame for the specified compound.
+
+ Args:
+ metrics_df: The metrics data frame.
+ compd: The specified compound.
+
+ Returns:
+ The metrics data frame for the specified compound.
+ """
+ start_idx = end_idx = None
+ for i, well in enumerate(metrics_df):
+ if compd in well and start_idx is None:
+ start_idx = i
+ elif start_idx is not None and well == '':
+ end_idx = i
+ break
+
+ if start_idx is None or end_idx is None:
+ return
+
+ compd_df = metrics_df.iloc[:, start_idx: end_idx + 1]
+
+ return compd_df
+
+ def compute_fold_changes(
+ self,
+ metrics_df: pd.DataFrame,
+ ctrl_df: pd.DataFrame,
+ ) -> pd.DataFrame:
+ """Computes fold changes for the metrics data frame.
+
+ Fold changes are computed relative to the control control compound.
+
+ Args:
+ metrics_df: The metrics data frame.
+ ctrl_df: A data frame with the metrics for the control compound.
+
+ Returns:
+ A metrics data frame with fold changes.
+ """
+ fld_chg_df = metrics_df.copy()
+ ctrl_idx = 0
+ for well in metrics_df:
+ if well != '':
+ fld_chg_df[well] /= ctrl_df[MEAN_COL]
+ fld_chg_df[well] *= 100
+ ctrl_idx += 1
+ else:
+ ctrl_idx = 0
+
+ fld_chg_df.fillna(0, inplace=True)
+
+ return fld_chg_df
+
+ def get_timepoints_dataframe(
+ self,
+ metrics_df: pd.DataFrame,
+ time_df: pd.DataFrame,
+ timepoints: list[int],
+ ) -> pd.DataFrame:
+ """Gets the metrics data frame for the specified time points only.
+
+ Args:
+ metrics_df: The metrics data frame.
+ time_df: The time data frame.
+ timepoints: A sequence of time points to select.
+
+ Returns:
+ The metrics data frame for the specified time points.
+ """
+ df = pd.concat([time_df, metrics_df], axis=1)
+ compds_df = df[time_df['Elapsed'].isin(timepoints)]
+
+ return compds_df
+
+ def split_dataframe(
+ self,
+ metrics_df: pd.DataFrame,
+ ) -> dict[str, dict[str, pd.DataFrame]] | None:
+ """Splits a data frame by empty columns into multiple data frames.
+
+ Args:
+ metrics_df: The metrics data frame.
+
+ Returns:
+ A dictionary of the split data frames, with keys of the compounds
+ and concentrations per compound.
+ """
+ compds_concs = self._get_compounds_and_concentrations(
+ metrics_df.iloc[:, 2::])
+ dfs = {}
+ i = 0
+ for j in range(0, len(metrics_df.columns)):
+ if metrics_df.columns[j] == '':
+ compd, conc = compds_concs[i].split(' ', 1)
+ compd_df = self.get_compound_dataframe(metrics_df,
+ compds_concs[i])
+ dfs.setdefault(compd, {})
+ compd_df = pd.concat([metrics_df['Elapsed'], compd_df], axis=1)
+ columns = compd_df['Elapsed']
+ compd_df = compd_df.iloc[:, 1:-1].transpose()
+ compd_df.columns = list(columns)
+ dfs[compd][conc] = compd_df
+ i += 1
+
+ return dfs
+
+ def generate_compound_summary_figs(
+ self,
+ veh_ctrl: str,
+ pos_ctrl: str,
+ neg_ctrl: str,
+ metric_threshold: int,
+ output_dir: Path,
+ dpi: int = 600,
+ ) -> None:
+ """Generates and saves figures visualizing experiment data.
+
+ Args:
+ veh_ctrl: The name of the vehicle control.
+ pos_ctrl: The name of the positive control.
+ neg_ctrl: The name of the negative control.
+ metric_threshold: The metric threshold to show in the generated
+ figures.
+ output_dir: The output directory to save figures in.
+ dpi: The dpi of the figures.
+ """
+ dfs = self.dfs
+ compds = list(dfs.keys())
+ num_ctrls = 0
+ for ctrl in [pos_ctrl, neg_ctrl]:
+ if ctrl in compds:
+ num_ctrls += 1
+ compds.remove(ctrl)
+
+ num_axes = len(compds) + num_ctrls
+ if veh_ctrl in compds:
+ num_axes -= 1
+ np.random.seed(0)
+ figs = {}
+ for compd in compds:
+ if compd == veh_ctrl:
+ continue
+ fig, axes = plt.subplots(num_axes, figsize=(6, 10), sharex=True)
+ if not isinstance(axes, list) and not isinstance(axes, np.ndarray):
+ axes = [axes]
+ i = 0
+ last_ctrl_idx = None
+ for ctrl, label in zip([neg_ctrl, pos_ctrl],
+ ['-ve\nControl', '+ve\nControl']):
+ try:
+ df = list(dfs[ctrl].values())[0]
+ except KeyError:
+ continue
+
+ self._plot_summary(df, axes[i], metric_threshold)
+ axes[i].set_ylabel(label)
+ last_ctrl_idx = i
+ i += 1
+
+ for conc, df in dfs[compd].items():
+ self._plot_summary(df, axes[i], metric_threshold)
+ axes[i].set_ylabel(conc)
+ i += 1
+ if last_ctrl_idx is not None:
+ axes[last_ctrl_idx].tick_params(axis='x', which='both',
+ bottom=False)
+ axes[last_ctrl_idx].spines['bottom'].set_linestyle((0, (8, 5)))
+ axes[last_ctrl_idx].spines['bottom'].set_color('red')
+
+ for x in range(0, i):
+ axes[x].spines['top'].set_visible(False)
+ axes[x].spines['right'].set_visible(False)
+ if x == len(axes) - 1 or last_ctrl_idx == x:
+ continue
+ axes[x].spines['bottom'].set_visible(False)
+ axes[x].axes.get_xaxis().set_visible(False)
+
+ plt.suptitle(compd, fontweight='bold', y=1)
+ plt.xlabel('Wound Closure Relative to VEH (%)')
+ fig.subplots_adjust(hspace=0)
+ plt.setp([a.get_xticklabels() for a in fig.axes[:-1]],
+ visible=False)
+ fig.tight_layout()
+ figs[compd] = plt.gcf()
+
+ for compd, fig in figs.items():
+ fig.savefig(os.path.join(output_dir, f'{compd}_wound_closure.png'),
+ dpi=dpi)
+ plt.close(fig)
+
+ def use_notes_compounds(
+ self,
+ metrics_df: pd.DataFrame,
+ info_df: pd.DataFrame,
+ ph_compds: list[str],
+ ) -> pd.DataFrame:
+ """Uses compounds from the experiment notes in the metrics data frame.
+
+ Hence replaces the existing (placeholder) compounds in the metrics data
+ frame header. The compounds in the notes must be separated by an
+ underscore e.g. "Notes: C55_C56_C57_C58".
+
+ Args:
+ metrics_df: The metrics data frame.
+ info_df: The experiment information data frame containing the
+ notes.
+ ph_compds: A sequence of names for the placeholder compounds to
+ replace in the metrics data frame header. Each compound in the
+ experiment notes will be mapped to each placeholder in this
+ sequence in order.
+ """
+ notes_compds = info_df.iloc[4][0].split('Notes: ')[1]
+ notes_compds = notes_compds.split('_')
+ compd_map = {ph_compd: notes_compd for ph_compd, notes_compd in zip(
+ ph_compds, notes_compds)}
+ columns = list(metrics_df.columns)
+
+ for i, df_compd in enumerate(columns):
+ df_compd = df_compd.split(' ')[0]
+ if df_compd in compd_map:
+ columns[i] = columns[i].replace(df_compd, compd_map[df_compd])
+ metrics_df.columns = columns
+
+ return metrics_df
+
+ def gen_analysed_excel(
+ self,
+ output_path: Path,
+ ) -> None:
+ """Generates an excel spreadsheet from data frames and saves as a file.
+
+ Args:
+ output_path: The path of the output excel file to create.
+ """
+ df = self.stats_df
+ fld_chg_df = self.fld_chg_stats_df
+ time_df = self.time_df
+ info_df = self.info_df
+ with pd.ExcelWriter(output_path) as writer:
+ workbook = writer.book
+ info_df.to_excel(writer, startrow=0, index=False, header=False)
+ ws = writer.sheets['Sheet1']
+ header_format = workbook.add_format({'bold': True,
+ 'valign': 'centre'})
+ old_headers = list(df.columns)
+ header_mapping2 = [x for x in old_headers]
+ header_mapping = [i for i, _ in enumerate(old_headers)]
+
+ old_headers = list(df.columns)
+ header_mapping2 = list(time_df.columns) + [x for x in old_headers]
+ header_mapping = [i for i, _ in enumerate(old_headers)]
+ df.columns = header_mapping
+ fld_chg_df.columns = header_mapping
+ df = pd.concat([time_df, df], axis=1)
+ fld_chg_df = pd.concat([time_df, fld_chg_df], axis=1)
+ df.columns = header_mapping2
+ fld_chg_df.columns = header_mapping2
+ old_headers = list(df.columns)
+ header_mapping = [i for i, _ in enumerate(old_headers)]
+
+ df.to_excel(writer, startrow=8, index=False, header=False)
+
+ mean_cols = [i for i, x in enumerate(old_headers) if x == STD_COL]
+ fld_chg_df.columns = pd.Index(header_mapping)
+ fld_chg_df_style = fld_chg_df.style.apply(self._flag, axis=0,
+ subset=mean_cols)
+ mean_cols = [i for i, x in enumerate(old_headers) if x == SEM_COL]
+ fld_chg_df_style.columns = pd.Index(header_mapping)
+ fld_chg_df_style = fld_chg_df_style.apply(self._flag, axis=0,
+ subset=mean_cols)
+
+ fld_chg_df_style.to_excel(writer, startrow=len(df) + 10,
+ index=False, header=False)
+ fld_chg_df.columns = header_mapping2
+ for col_num, value in enumerate(df.columns.values):
+ ws.write(7, col_num, value, header_format)
+
+ for col_num, value in enumerate(fld_chg_df.columns.values):
+ ws.write(len(df) + 9, col_num, value, header_format)
+
+ for i, wdh in enumerate(self._comp_col_wdhs(df)):
+ ws.set_column(i, i, wdh)
+
+ for i in range(7, len(df) + 10 + len(df)):
+ cell_format = workbook.add_format({'valign': 'centre'})
+ ws.set_row(i, cell_format=cell_format)
+
+
+@click.command()
+@click.argument('root_directory', type=click.Path(
+ exists=True, file_okay=False))
+@click.option('--vehicle-control', default=VEHICLE_CONTROL, show_default=True,
+ help='Vehicle control used in the experiment.')
+@click.option('--positive-control', default=POSITIVE_CONTROL,
+ show_default=True,
+ help='Positive control used in the experiment.')
+@click.option('--negative-control', default=NEGATIVE_CONTROL,
+ show_default=True,
+ help='Negative control used in the experiment')
+@click.option('--placeholder-compounds', required=True, show_default=True,
+ default=PLACEHOLDER_COMPOUNDS, help='The placeholder '
+ 'compound names (to be replaced with names from the \'Notes:\' '
+ 'section) in the main header of input text files.')
+@click.option('--do-not-use-notes-compounds', is_flag=True,
+ help='Do not use compound names listed in the \'Notes\' section '
+ 'of input text files (by mapping compounds names in notes to '
+ 'compound name placeholders in the main header columns), '
+ 'instead use compound names in the main header.')
+@click.option('--do-not-generate-figures', is_flag=True,
+ help='Do not generate box plot figures for the wound closure '
+ 'over vehicle control (%) at various time points and '
+ 'concentrations to summarize compound performance.')
+@click.option('--figure-timepoints', required=True, show_default=True,
+ default=FIGURE_TIMEPOINTS, help='The time points to show (in '
+ 'hours) in the generated figures.')
+@click.option('--figure-metric-threshold', default=FIGURE_METRIC_THRESHOLD,
+ show_default=True,
+ help='The metric threshold to show in the generated figure.')
+def metrics_file_processing(
+ root_directory: str,
+ vehicle_control: str = VEHICLE_CONTROL,
+ positive_control: str = POSITIVE_CONTROL,
+ negative_control: str = NEGATIVE_CONTROL,
+ placeholder_compounds: str = PLACEHOLDER_COMPOUNDS,
+ do_not_use_notes_compounds: bool = DO_NOT_USE_NOTES_COMPOUNDS,
+ do_not_generate_figures: bool = DO_NOT_GENERATE_FIGURES,
+ figure_timepoints: str = FIGURE_TIMEPOINTS,
+ figure_metric_threshold: int = FIGURE_METRIC_THRESHOLD,
+) -> None:
+ """Processes raw .txt files containing live cell imaging metrics.
+
+ The .txt files are those generated by Incuctye Software from a live cell
+ imaging experiment, such as airway epithelium wound closure experiments
+ utilizing, for example, IncuCyte® ImageLock 96-well plates, IncuCyte®
+ ZOOM, etc, and, for example, various drug compounds, such as DMSO for
+ control, etc. From these input files, generates data such as image figures
+ and excel spreed sheets for analysis.
+
+ ROOT_DIRECTORY:
+
+ The directory to search for .txt files to process in. When using the web
+ interface, directory must be zipped.
+ """
+ try:
+ fig_tpts = [int(t) for t in figure_timepoints.split()]
+ except ValueError:
+ click.echo('Invalid value provided for \'...--figure-timepoints\' '
+ 'option.')
+ return
+
+ for f in [f for f in Path(root_directory).iterdir() if f.is_file() and
+ f.suffix == '.txt']:
+ processor = MetricsTxtFileProcessor(f)
+ processor.process(not do_not_use_notes_compounds,
+ placeholder_compounds.split(), vehicle_control,
+ fig_tpts)
+ output_dir = f.parent / f.name.replace('.txt', '_txt')
+ output_dir.mkdir(exist_ok=True)
+
+ output_excel_file = output_dir / (f.stem + '_analysed.xlsx')
+ processor.gen_analysed_excel(output_excel_file)
+
+ if not do_not_generate_figures:
+ processor.generate_compound_summary_figs(
+ vehicle_control.split(' ')[0],
+ positive_control.split(' ')[0],
+ negative_control.split(' ')[0], figure_metric_threshold,
+ output_dir)
diff --git a/bimana/tight_junctions/__init__.py b/bimana/tight_junctions/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bimana/tight_junctions/analysis.py b/bimana/tight_junctions/analysis.py
new file mode 100644
index 0000000..b96280e
--- /dev/null
+++ b/bimana/tight_junctions/analysis.py
@@ -0,0 +1,125 @@
+from typing import Any
+
+import cv2
+import numpy as np
+import numpy.typing as npt
+
+from bimana.utils.deep_learning.dexined import detect_edges
+from bimana.utils.image_processing import (ImageChannel, auto_segment_image,
+ binary_to_bgr_image,
+ detect_circular_objects,
+ extract_channel)
+
+
+def extract_tight_junctions(
+ img: npt.NDArray[Any],
+ tight_junction_channel: ImageChannel,
+) -> tuple[npt.NDArray[np.bool_], list[tuple[str, npt.NDArray[np.uint8]]]]:
+ """Extracts stained tight junctions present in a fluorescent image.
+
+ Args:
+ img: A colour image.
+ tight_junction_channel: The image channel with the stained tight
+ junctions.
+
+ Returns:
+ A binary image where the stained tight junctions present in the
+ fluorescent image are the foreground. Also returns a sequence of the
+ intermediate images generated during processing.
+ """
+ grey = extract_channel(img, tight_junction_channel)
+ edges = detect_edges(grey)
+ bin_img = ~auto_segment_image(edges)
+ tight_juncs = grey.copy()
+ tight_juncs[bin_img] = 0
+
+ procd_imgs = []
+ procd_imgs.append(('tight junctions image channel', grey))
+ procd_imgs.append(('tight junctions detected edges', edges))
+ procd_imgs.append(('tight junctions binary mask',
+ binary_to_bgr_image(bin_img)))
+ procd_imgs.append(('tight junctions', tight_juncs))
+
+ return bin_img, procd_imgs
+
+
+def segment_cells(
+ img: npt.NDArray[Any],
+ cell_channel: ImageChannel,
+ min_dist: int = 12,
+ alpha: int = 10,
+ beta: int = 14,
+ min_radius: int = 5,
+ max_radius: int = 15,
+ min_obj_area: int = 20,
+ bgd_px_thresh: int = 20,
+) -> tuple[list[npt.NDArray[Any]], list[tuple[str, npt.NDArray[np.uint8]]]]:
+ """Segments stained circular cells present in a fluorescent image.
+
+ Args:
+ img: A colour image.
+ cell_channel: The image channel with the stained cells.
+ min_dist: The minimum distance between the centers of the cells in
+ pixels.
+ alpha: A parameter that can be fine tuned for cell segmentation
+ performance. It may be decreased to identify more objects.
+ beta: A parameter that can be fine tuned for cell segmentation
+ performance. The smaller it is, the more false cells may be
+ identified.
+ min_radius: The minimum radius of cells in pixels.
+ max_radius: The maximum radius of cells in pixels.
+ min_obj_area: The minimum area of cells in pixels².
+ bgd_px_thresh: The maximum value of background pixels in the image.
+
+ Returns:
+ A binary image where the stained tight junctions present in the
+ fluorescent image are the foreground. Also returns a dictionary of the
+ intermediate images generated during processing.
+ """
+ grey = extract_channel(img, cell_channel)
+ cells = detect_circular_objects(grey, min_dist, alpha, beta, min_radius,
+ max_radius, min_obj_area, bgd_px_thresh)
+
+ procd_imgs = []
+ procd_imgs.append(('cell image channel', grey))
+ cell_img = img.copy()
+ cv2.drawContours(cell_img, cells, -1, (0, 0, 255), 2)
+ procd_imgs.append(('cells', cell_img))
+
+ return cells, procd_imgs
+
+
+NUM_LINES = 10
+
+
+def perform_ijoq(bin_img: npt.NDArray[np.bool_]) -> float:
+ """Perform intercellular junction organization quantification (IJOQ).
+
+ IJOQ: https://www.frontiersin.org/articles/10.3389/fcimb.2022.865528.
+ Code adapted from: https://github.com/DevonsMo/IJOQ.
+
+ Args:
+ bin_img: A binary image containing tight junctions as the foreground.
+
+ Returns:
+ The IJOQ value in the original image.
+ """
+ cell_border_frequency = 0
+ for axis in range(2):
+ for i in range(NUM_LINES):
+ pixel = round((i + 0.5) * bin_img.shape[axis] / NUM_LINES)
+ previous_pixel = bin_img[0, pixel] if axis else bin_img[pixel, 0]
+ for j in range(1, bin_img.shape[1 - axis]):
+ current_pixel = (bin_img[j, pixel] if axis else
+ bin_img[pixel, j])
+ # if the line detects a color change (i.e. black to white or
+ # white to black)
+ if previous_pixel != current_pixel:
+ cell_border_frequency += 0.5 / bin_img.shape[1 - axis]
+
+ # set current pixel as the previous pixel before moving to the
+ # next pixel
+ previous_pixel = current_pixel
+
+ # take average of all lines
+ return round(cell_border_frequency / (2 * NUM_LINES), 4)
diff --git a/bimana/tight_junctions/commands.py b/bimana/tight_junctions/commands.py
new file mode 100644
index 0000000..98e8ba5
--- /dev/null
+++ b/bimana/tight_junctions/commands.py
@@ -0,0 +1,208 @@
+from collections import defaultdict
+from pathlib import Path
+
+import click
+import numpy as np
+
+from bimana.tight_junctions.analysis import (extract_tight_junctions,
+ perform_ijoq, segment_cells)
+from bimana.utils.file_processing import (DirFormat, get_dirs, load_imgs,
+ save_csv, save_imgs)
+from bimana.utils.image_processing import (MAX_PX_VAL, ImageChannel,
+ extract_channel)
+from bimana.utils.quantification import (
+ area, aspect_ratio, circularity, gen_histogram, gen_stats,
+ num_connected_components, perimeter, roundness, size_connected_components,
+ solidity)
+
+DIR_FORMAT = DirFormat(1).name
+TIGHT_JUNC_STAIN_COL = ImageChannel(2).name
+CELL_STAIN_COL = ImageChannel(1).name
+MIN_DIST = 12
+ALPHA = 10
+BETA = 14
+MIN_RADIUS = 5
+MAX_RADIUS = 15
+MIN_AREA = 20
+BACKGROUND_PIXEL_THRESH = 20
+DONT_SAVE_PROCD_IMGS = False
+METRICS_CSV_FILENAME = 'metrics.csv'
+
+
+@click.command()
+@click.argument('root_directory', type=click.Path(
+ exists=True, file_okay=False))
+@click.option('--analyse-tight-junctions', is_flag=True,
+ help='Analyse tight junctions in the image e.g. by performing '
+ 'intercellular junction organization quantification.')
+@click.option('--analyse-cells', is_flag=True,
+ help='Analyse cells in the image e.g. by generating cell shape '
+ 'metrics.')
+@click.option('--directory-format', type=click.Choice([DirFormat(1).name,
+ DirFormat(2).name, DirFormat(3).name], case_sensitive=False),
+ default=DIR_FORMAT, show_default=True,
+ help='Location of image files to process in the root directory '
+ f'tree - if set to {DirFormat(1).name}, processes images '
+ f'in the root directory; if set to {DirFormat(2).name}, '
+ 'processes images in subdirectories of the root directory; '
+ f' if set to {DirFormat(3).name}, processes images '
+ 'in all directories of the root directory tree.')
+@click.option('--tight-junction-stain-colour', type=click.Choice(
+ [ImageChannel(1).name, ImageChannel(2).name,
+ ImageChannel(3).name], case_sensitive=False),
+ default=TIGHT_JUNC_STAIN_COL, show_default=True,
+ help='The primary colour (or one of) that the tight junction '
+ 'stain is composed of.')
+@click.option('--cell-stain-colour', type=click.Choice(
+ [ImageChannel(1).name, ImageChannel(2).name,
+ ImageChannel(3).name], case_sensitive=False),
+ default=CELL_STAIN_COL, show_default=True, help='The primary '
+ 'colour (or one of) that the cell stain is composed of.')
+@click.option('--min-dist', type=click.IntRange(0),
+ default=MIN_DIST, show_default=True,
+ help='The minimum distance between the centers of cells in '
+ 'pixels.')
+@click.option('--alpha', type=click.IntRange(0), default=ALPHA,
+ show_default=True,
+ help='A parameter that can be fine tuned for cell segmentation '
+ 'performance; it may be decreased to identify more '
+ 'objects.')
+@click.option('--beta', type=click.IntRange(0), default=BETA,
+ show_default=True,
+ help='A parameter that can be fine tuned for cell segmentation '
+ 'performance; the smaller it is, the more false cells may '
+ 'be identified.')
+@click.option('--min-radius', type=click.IntRange(0), default=MIN_RADIUS,
+ show_default=True, help='The minimum radius of cells in pixels.')
+@click.option('--max-radius', type=click.IntRange(0), default=MAX_RADIUS,
+ show_default=True, help='The maximum radius of cells in pixels.')
+@click.option('--min-area', type=click.IntRange(0), default=MIN_AREA,
+ show_default=True, help='The minimum area of cells in pixels.')
+@click.option('--background-pixel-thresh', type=click.IntRange(0, MAX_PX_VAL),
+ default=BACKGROUND_PIXEL_THRESH, show_default=True,
+ help='The maximum intensity of background pixels in the '
+ 'greyscale image.')
+@click.option('--no-image-processing-visualization', is_flag=True,
+ help='Do not save image files visualizing different stages of '
+ 'image processing.')
+def tight_junction_analysis(
+ root_directory: str | Path,
+ analyse_tight_junctions: bool,
+ analyse_cells: bool,
+ directory_format: str = DIR_FORMAT,
+ tight_junction_stain_colour: str = TIGHT_JUNC_STAIN_COL,
+ cell_stain_colour: str = CELL_STAIN_COL,
+ min_dist: int = MIN_DIST,
+ alpha: int = ALPHA,
+ beta: int = BETA,
+ min_radius: int = MIN_RADIUS,
+ max_radius: int = MAX_RADIUS,
+ min_area: int = MIN_AREA,
+ background_pixel_thresh: int = BACKGROUND_PIXEL_THRESH,
+ no_image_processing_visualization: bool = DONT_SAVE_PROCD_IMGS,
+) -> None:
+ """Analyse fluorescent tight junction images.
+
+ Analysis is performed with respect to the tight junctions (e.g. by
+ performing intercellular junction organization quantification) and/or cells
+ (e.g. by generating cell shape metrics) present in the image. By default,
+ saves generated data in the root directory tree.
+
+ ROOT_DIRECTORY:
+
+ The directory to search for images to process in. When using the web
+ interface, directory must be zipped.
+
+
+ IMPORTANT NOTES
+
+ Default option values:
+
+ The default option values were fine tuned for processing fluorescent images
+ containing several tightly packed airway epithelial cells (stained blue)
+ and tight junctions (stained green), for example,
+ https://github.com/AlphonsG/BIMANA
+ """
+ # check inputs
+ if not (analyse_tight_junctions or analyse_cells):
+ click.echo('Invalid inputs: --analyse-tight-junctions and/or '
+ '--analyse-cells option(s) must be selected.')
+ return
+
+ root_dir = output_dir = Path(root_directory)
+ output_dirs = []
+ metrics = defaultdict(list)
+
+ for curr_dir in get_dirs(root_dir, DirFormat[directory_format]):
+ if curr_dir in output_dirs: # previously generated output directory
+ continue
+ for filename, img in load_imgs(curr_dir):
+ curr_output_dir = output_dir / curr_dir.relative_to(
+ root_dir) / f'{filename.stem}_{filename.suffix[1:]}'
+ output_dirs.append(curr_output_dir)
+
+ metrics['Image'].append(filename.name)
+ metrics['File path'].append(str(filename))
+
+ procd_imgs = []
+ if analyse_tight_junctions:
+ tight_juncs, curr_procd_imgs = extract_tight_junctions(
+ img, ImageChannel[tight_junction_stain_colour])
+
+ procd_imgs += curr_procd_imgs
+
+ img_tight_junc_chn = extract_channel(
+ img, ImageChannel[tight_junction_stain_colour]).astype(
+ float)
+ img_tight_junc_chn[~tight_juncs] = np.nan
+ tight_junc_px = img_tight_junc_chn.flatten()
+ tight_junc_intsty = (tight_junc_px / MAX_PX_VAL * 100).tolist()
+ stats = gen_stats(tight_junc_intsty)
+ for name, stat in stats.items():
+ metrics['Tight Junction Pixel Intensity (%) '
+ f'({name})'].append(stat)
+ curr_output_dir.mkdir(parents=True, exist_ok=True)
+ gen_histogram({'Tight Junction Pixel Intensity (%)':
+ tight_junc_intsty}, curr_output_dir)
+
+ metrics['Intercellular Junction Organization '
+ 'Quantification (AU)'].append(
+ perform_ijoq(tight_juncs))
+ metrics['Number of Tight Junction Fragments'].append(
+ num_connected_components(tight_juncs))
+
+ tight_junc_sizes = size_connected_components(tight_juncs)
+ stats = gen_stats(tight_junc_sizes)
+ for name, stat in stats.items():
+ metrics['Tight Junction Fragment Size (No. Pixels) '
+ f'({name})'].append(stat)
+ gen_histogram({'Tight Junction Fragment Size (No. Pixels)':
+ tight_junc_sizes}, curr_output_dir)
+
+ if analyse_cells:
+ cells, curr_procd_imgs = segment_cells(
+ img, ImageChannel[cell_stain_colour], min_dist, alpha,
+ beta, min_radius, max_radius, min_area,
+ background_pixel_thresh)
+
+ procd_imgs += curr_procd_imgs
+
+ metrics['Number of Cells'].append(len(cells))
+ data = {'Cell Area (No. Pixels)': area(cells),
+ 'Cell Aspect Ratio (AU)': aspect_ratio(cells),
+ 'Cell Circularity (AU)': circularity(cells),
+ 'Cell Perimeter (No. Pixels)': perimeter(cells),
+ 'Cell Roundness (AU)': roundness(cells),
+ 'Cell Solidity (AU)': solidity(cells)}
+
+ for data_name, data in data.items():
+ stats = gen_stats(data)
+ for stat_name, stat in stats.items():
+ metrics[f'{data_name} ({stat_name})'].append(stat)
+ gen_histogram({data_name: data}, curr_output_dir)
+
+ if not no_image_processing_visualization:
+ save_imgs(procd_imgs, curr_output_dir)
+
+ # save metrics
+ save_csv(metrics, output_dir / METRICS_CSV_FILENAME)
diff --git a/bimana/utils/__init__.py b/bimana/utils/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/bimana/utils/commands.py b/bimana/utils/commands.py
new file mode 100644
index 0000000..e9c29a5
--- /dev/null
+++ b/bimana/utils/commands.py
@@ -0,0 +1,23 @@
+def parse_input_bgr(
+ input_bgr: tuple[str, str, str],
+) -> tuple[int | float, int | float, int | float]:
+ """Parses input BGR pixel values.
+
+ Converts input BGR values from strings (of raw pixel values between 0 and
+ 255) to integers or from strings (of pixel intensity values between 0.0
+ and 1.0) to floats.
+
+ Args:
+ input_bgr: A sequence of BGR values as strings.
+
+ Returns:
+ A sequence of parsed BGR pixel values.
+ """
+ output_bgr = []
+ for val in input_bgr:
+ try:
+ output_bgr.append(int(val))
+ except ValueError:
+ output_bgr.append(float(val))
+
+ return tuple(output_bgr)
diff --git a/bimana/utils/deep_learning/dexined.py b/bimana/utils/deep_learning/dexined.py
new file mode 100644
index 0000000..7914677
--- /dev/null
+++ b/bimana/utils/deep_learning/dexined.py
@@ -0,0 +1,68 @@
+import sys
+import warnings
+from pathlib import Path
+from types import SimpleNamespace
+
+import numpy as np
+import numpy.typing as npt
+
+DEXINET_DIR = Path(__file__).parents[3] / 'third_party/DexiNed'
+sys.path.insert(1, str(DEXINET_DIR))
+# try importing Pytorch
+try:
+ import torch
+ from torch.utils.data import DataLoader
+ from datasets import TestDataset
+ from main import test
+ from model import DexiNed
+except ModuleNotFoundError as e:
+ if e.msg == 'torch':
+ msg = ('Bimana could not import PyTorch - deep learning functions '
+ 'will not be available. Ensure Pytorch is correctly installed '
+ 'to utilise these functions: '
+ 'https://pytorch.org/get-started/locally/. Reason for import '
+ f'failure: {repr(e)}')
+ warnings.warn(msg)
+ else:
+ raise
+
+
+ARGS = SimpleNamespace()
+ARGS.is_testing = True
+ARGS.test_data = 'CLASSIC'
+TEST_IMG_HEIGHT, TEST_IMG_WIDTH = 512, 512
+MEAN_PIXEL_VALUES = [103.939, 116.779, 123.68]
+CHECKPOINT_PATH = (Path(__file__).parents[3] / 'misc/checkpoints/DexiNed/'
+ 'BIPED/10/10_model.pth')
+
+
+def detect_edges(
+ img: npt.NDArray[np.uint8],
+ gpu: bool = False,
+) -> npt.NDArray[np.uint8]:
+ """Detects edges in an image using DexiNed.
+
+ DexiNed: https://arxiv.org/pdf/2112.02250.pdf.
+
+ Args:
+ img: An image.
+ gpu: If true, will use the GPU for edge detection.
+
+ Returns:
+ A greyscale image of the edges from the original image.
+ """
+ device = torch.device('cuda' if gpu and torch.cuda.device_count() > 0 else
+ 'cpu')
+ model = DexiNed().to(device)
+
+ if len(img.shape) == 2:
+ img = img[..., None]
+ img = np.repeat(img, 3, 2)
+ dataset_val = TestDataset(None, ARGS.test_data, MEAN_PIXEL_VALUES,
+ TEST_IMG_HEIGHT, TEST_IMG_WIDTH, imgs=[img])
+ dataloader_val = DataLoader(dataset_val)
+
+ avg_img, _ = test(CHECKPOINT_PATH, dataloader_val, model, device, None,
+ ARGS)[0]
+
+ return ~avg_img
diff --git a/bimana/utils/file_processing.py b/bimana/utils/file_processing.py
new file mode 100644
index 0000000..1f3e3a8
--- /dev/null
+++ b/bimana/utils/file_processing.py
@@ -0,0 +1,189 @@
+import os
+import platform
+import struct
+import warnings
+from enum import Enum
+from pathlib import Path
+from typing import Any
+
+os.environ["OPENCV_IO_MAX_IMAGE_PIXELS"] = '1000000000000'
+
+import cv2
+import numpy.typing as npt
+import pandas as pd
+from natsort import natsorted
+
+# try to import vips
+if platform.system() == 'Windows' and struct.calcsize("P") * 8 == 64:
+ VIPS_HOME_DIR = (Path(__file__).parents[2] / 'third_party/'
+ 'vips-dev-w64-web-8.13.3/vips-dev-8.13/bin')
+ os.environ['PATH'] = str(VIPS_HOME_DIR) + ';' + os.environ['PATH']
+
+if platform.system() == 'Windows' and '64' not in platform.machine():
+ msg = ('Bimana requires 64-bit Python on Windows, some functions may fail '
+ 'given the current configuration.')
+ warnings.warn(msg)
+else:
+ try:
+ import pyvips
+ except ImportError as e:
+ msg = ('Bimana could not import Pyvips, some functions may fail. '
+ 'Unix-like operating system and MacOS users, please ensure '
+ 'vips is installed: https://www.libvips.org/install.html. '
+ f'Reason for import failure: {repr(e)}')
+ warnings.warn(msg)
+
+IMAGE_FEX = '.png'
+IMAGE_FILE_STEM = 'image'
+
+
+class DirFormat(Enum):
+ """Find_dirs flags.
+
+ ROOT: If set, gets the path to the root directory if it contains at least
+ one file.
+ SUB: If set, gets the paths to file-containing subdirectories of the root
+ directory.
+ RECURSIVE: If set, gets the paths to all file-containing directories in
+ the root directory tree.
+ """
+
+ ROOT = 1
+ SUB = 2
+ RECURSIVE = 3
+
+
+def get_dirs(root_dir: Path, flag: DirFormat) -> list[Path]:
+ """Gets the paths to directories with files from the root directory tree.
+
+ Args:
+ root_dir: The path to the root directory.
+ flag: A flag that can take values of DirFormat.
+
+ Returns:
+ A sequence of paths to file-containing directories.
+ """
+ match flag:
+ case flag.ROOT:
+ dirs = ([root_dir] if len([f for f in root_dir.iterdir() if
+ f.is_file()]) != 0 else [])
+ case flag.SUB:
+ dirs = [curr_dir for curr_dir in root_dir.iterdir() if
+ curr_dir.is_dir() and len([f for f in curr_dir.iterdir() if
+ f.is_file()]) != 0]
+ case flag.RECURSIVE:
+ dirs = []
+ for curr_root_dir, _, files in os.walk(root_dir):
+ if len(files) != 0:
+ dirs.append(Path(curr_root_dir))
+
+ return dirs
+
+
+def load_imgs(
+ input_dir: Path,
+ shrink_factor: int | None = None,
+) -> list[tuple[Path, npt.NDArray[Any]]]:
+ """Loads images from a directory.
+
+ Args:
+ input_dir: A directory containing image files.
+ shrink_factor: Factor to shrink images by before loading them into
+ memory.
+
+ Returns:
+ A sequence of images (and the corresponding image file path) for all
+ successfully loaded images. The sequence is naturally sorted according
+ to the image file paths.
+ """
+ # get paths of files in directory
+ files = natsorted([f for f in input_dir.iterdir() if f.is_file()])
+
+ # load images
+ imgs = []
+ if shrink_factor is None:
+ imgs += [(f, img) for f in files if (img := cv2.imread(str(f))) is not
+ None] # TODO cv2 size error?
+ else:
+ for f in files:
+ if f.suffix == '.csv':
+ continue
+ try:
+ img = pyvips.Image.new_from_file(str(f))
+ img = img.shrink(shrink_factor, shrink_factor)
+ except Exception as e:
+ msg = (f'Failed to open or shrink file \'{f}\' as '
+ f'image: {repr(e)}')
+ warnings.warn(msg)
+ continue
+ img = img.numpy()
+ img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
+ imgs.append((f, img))
+
+ return imgs
+
+
+def save_imgs(
+ imgs: list[tuple[str, npt.NDArray[Any]]],
+ output_dir: Path,
+) -> None:
+ """Saves images to a directory.
+
+ Args:
+ imgs: A list of filename (without the extension) and image pairs.
+ Images are saved with the corresponding filename in a predefined
+ lossless format.
+ output_dir: The directory to save images to.
+ """
+ for img in imgs:
+ path = output_dir / (img[0] + IMAGE_FEX)
+ cv2.imwrite(str(path), img[1])
+
+
+def save_csv(data: dict[Any, Any], csv_path: Path) -> None:
+ """Saves a csv file with the given data in the specified path.
+
+ Args:
+ data: The data to save where the keys will be the headers and the
+ values will be the rows in the csv file.
+ csv_path: The path to the csv file to save.
+ """
+ df = pd.DataFrame(data)
+ df.to_csv(csv_path, index=False, encoding='utf-8-sig')
+
+
+def crop_and_save_images(
+ path: Path,
+ coords: npt.NDArray[Any],
+ skip_existing: bool = False,
+) -> list[Path]:
+ """Crops an image without loading it into memory and saves sub-images.
+
+ Useful for dividing an image too large to load into memory into sub-images
+ that can. Sub-images will be saved as .png files each in a subdirectory
+ created in the same directory as the input image.
+
+ Args:
+ path: The file path to an image.
+ coords: An array of the (x1, y1, x2, y2) coordinates of the bounding
+ boxes for sub-images to crop in the image.
+ skip_existing: If true, will not overwrite existing files with same
+ names as generated subimage names.
+
+ Returns:
+ The file paths of the saved images.
+ """
+ output_dirs = []
+ img = pyvips.Image.new_from_file(str(path))
+ for x1, y1, x2, y2 in coords:
+ h, w = y2 - y1, x2 - x1
+ crop = img.crop(x1, y1, w, h)
+ file_stem = f'{path.stem}_{x1}x1_{y1}y1_{x2}x2_{y2}y2'
+ output_dir = path.parent / (file_stem + path.suffix.replace('.', '_'))
+ output_dir.mkdir(exist_ok=True)
+ output_path = (output_dir / file_stem).with_suffix('.png')
+ if not skip_existing or not output_path.is_file():
+ crop.pngsave(str(output_path))
+ output_dirs.append(output_dir)
+
+ return output_dirs
diff --git a/bimana/utils/image_processing.py b/bimana/utils/image_processing.py
new file mode 100644
index 0000000..525cbf2
--- /dev/null
+++ b/bimana/utils/image_processing.py
@@ -0,0 +1,557 @@
+from enum import Enum
+from typing import Any
+
+import cv2
+import numpy as np
+import numpy.typing as npt
+from scipy.signal import find_peaks
+from scipy.spatial import KDTree
+
+MAX_PX_VAL = 255
+KSIZE = 5
+BLOCKSIZE = 11
+C = 2
+DP = 1
+
+
+class ImageChannel(Enum):
+ """Get_channel flags.
+
+ BLUE: If set, extracts the blue channel.
+ GREEN: If set, extracts the green channel.
+ RED: If set, extracts the red channel.
+ """
+
+ BLUE = 1
+ GREEN = 2
+ RED = 3
+
+
+def segment_image(
+ img: npt.NDArray[Any],
+ lower_bgr: npt.NDArray[np.int_],
+ upper_bgr: npt.NDArray[np.int_],
+) -> npt.NDArray[np.bool_]:
+ """Segments an image.
+
+ Converts a colour image to a binary image where pixels with BGR values
+ between (inclusive) the specified upper and lower bounds are the foreground
+ (with pixel values of 1).
+
+ Args:
+ img: A colour image.
+ lower_bgr: The lower bound of BGR pixel values (all between 0 and 255)
+ to segment.
+ upper_bgr: The upper bound of BGR pixel values (all between 0 and 255)
+ to segment.
+
+ Returns:
+ A binary image where pixels with the specified values in the original
+ image are the foreground.
+ """
+ # threshold image to binary
+ return (cv2.inRange(img, lower_bgr, upper_bgr).astype(
+ float) / MAX_PX_VAL).astype(bool)
+
+
+def scale_bgr_values(
+ bgr: tuple[int | float, int | float, int | float],
+) -> npt.NDArray[np.int_]:
+ """Scales normalized BGR pixels from [0.0, 1.0] to [0, 255].
+
+ Ignored individual pixel values that are already un-normalized (int).
+
+ Args:
+ bgr: A sequence of BGR pixel values (each between 0 and 255
+ or normalized between 0.0 and 1.0).
+
+ Returns:
+ A sequence of un-normalized BGR pixel values (all between 0 and 255).
+ """
+ return np.array([round(val * MAX_PX_VAL) if isinstance(val, float)
+ else val for val in bgr])
+
+
+def remove_isolated_segmented_objects(
+ bin_img: npt.NDArray[np.bool_],
+ threshold: float = 0.2,
+) -> npt.NDArray[np.bool_]:
+ """Removes isolated objects segmented in an image.
+
+ Removes segmented objects in a binary image that are spatially isolated. A
+ segmented object is isolated if the proportion of the number of foreground
+ pixels along the width of the image at the height of the object's vertical
+ centre to the total number of points along the width of the image with at
+ least one foreground pixel at any height is below a threshold.
+
+ Args:
+ bin_img: A binary image.
+ threshold: The sensitivity, between 0 and 1, of the algorithm to
+ isolated objects. Larger values reduce the strictness of the
+ criteria objects must meet to be classified as isolated.
+
+ Returns:
+ A binary image without isolated segmented objects.
+ """
+ # find all individual segmented objects
+ cnts, _ = cv2.findContours(bin_img.astype(np.uint8), cv2.RETR_LIST,
+ cv2.CHAIN_APPROX_NONE)
+
+ # filter isolated objects
+ num_nonzero_cols = np.count_nonzero(np.sum(bin_img, 0))
+ summed_rows = np.sum(bin_img, 1)
+ dens_of_rows = summed_rows / num_nonzero_cols
+ iso_cnts = [cnt for cnt in cnts if dens_of_rows[cnt[:, 0, 1].min() + round(
+ (cnt[:, 0, 1].max() - cnt[:, 0, 1].min()) / 2)] < threshold]
+
+ # remove isolated objects from binary image
+ fltd_img = bin_img.astype(np.uint8)
+ cv2.drawContours(fltd_img, iso_cnts, -1, 0, cv2.FILLED)
+
+ cnts, _ = cv2.findContours(fltd_img, cv2.RETR_EXTERNAL,
+ cv2.CHAIN_APPROX_NONE)
+ fin_cnts, pts = [], []
+ area1, dist, area2 = 50 * threshold, 300 * threshold, 1062.5 * threshold
+ for i, c in enumerate(cnts):
+ if cv2.contourArea(c) > area1:
+ x, y, w, h = cv2.boundingRect(c)
+ pts.append((x + w / 2, y + h / 2))
+ fin_cnts.append(c)
+
+ tree = KDTree(pts)
+ _, xs = tree.query(pts, 3, distance_upper_bound=dist)
+ fin_img = np.zeros(bin_img.shape).astype(np.uint8)
+ for i, x in enumerate(xs):
+ if cv2.contourArea(fin_cnts[i]) >= area2:
+ cv2.drawContours(fin_img, [fin_cnts[i]], -1, 1, cv2.FILLED)
+ if len(pts) in x:
+ continue
+ cv2.drawContours(fin_img, [fin_cnts[i]], -1, 1, cv2.FILLED)
+
+ return fin_img.astype(bool)
+
+
+def bound_foreground(
+ bin_img: npt.NDArray[np.bool_],
+) -> tuple[list[npt.NDArray[Any]], list[npt.NDArray[Any]]]:
+ """Vertically bounds the foreground across the width of a binary image.
+
+ Generates an upper and lower polyline representing the coordinates of the
+ uppermost and lowermost, respectively, foreground pixels across the width
+ of the binary image.
+
+ Args:
+ bin_img: A binary image.
+
+ Returns:
+ The x-coordinates of the uppermost and lowermost foreground pixels
+ across the image and the corresponding y-coordinates of the uppermost
+ and lowermost foreground pixels across the image.
+ """
+ upper_lower_xs, upper_lower_ys = [], []
+ for lower, (start, step) in enumerate([[0, 1], [
+ bin_img.shape[0] - 1, -1]]):
+ # get all x-coordinates along the width of the binary image with at
+ # least one foreground pixel at any height
+ xs = np.argwhere(np.any(bin_img, axis=0))[:, 0]
+
+ # determine the y-coordinates of the uppermost/lowermost foreground
+ # pixel for each x-coordinate
+ ys = (bin_img[start:None:step, :] == 1).argmax(axis=0)
+ ys = np.take(ys, xs)
+ if lower:
+ ys = bin_img.shape[0] - ys - 1
+
+ upper_lower_xs.append(xs)
+ upper_lower_ys.append(ys)
+
+ return upper_lower_xs, upper_lower_ys
+
+
+def bounded_foreground_polyline(
+ upper_lower_xs: list[npt.NDArray[Any]],
+ upper_lower_ys: list[npt.NDArray[Any]],
+) -> npt.NDArray[Any]:
+ """Generates a polyline of the vertically bounded foreground in an image.
+
+ Combines the x-coordinates of the uppermost and lowermost foreground pixels
+ across a binary image and the corresponding y-coordinates of the uppermost
+ and lowermost foreground pixels across the image into a single closed
+ polyline enclosing all foreground pixels.
+
+ Args:
+ upper_lower_xs: The x-coordinates of the uppermost and lowermost
+ foreground pixels across a binary image.
+ upper_lower_ys: The y-coordinates of the uppermost and lowermost
+ foreground pixels across a binary image.
+
+ Returns:
+ A polyline of xy-coordinates enclosing all foreground pixels in the
+ source binary image.
+ """
+ xs = ys = np.array([], dtype=int)
+ for lower, (curr_xs, curr_ys) in enumerate(zip(
+ upper_lower_xs, upper_lower_ys)):
+ if lower:
+ curr_xs, curr_ys = curr_xs[::-1], curr_ys[::-1]
+
+ xs, ys = np.concatenate([xs, curr_xs]), np.concatenate([ys, curr_ys])
+
+ return np.array([[x, y] for x, y in zip(xs, ys)])
+
+
+def smooth_foreground_bounds(
+ bin_img: npt.NDArray[np.bool_],
+ upper_lower_xs: list[npt.NDArray[Any]],
+ upper_lower_ys: list[npt.NDArray[Any]],
+) -> tuple[list[npt.NDArray[Any]], list[npt.NDArray[Any]]]:
+ """Smooths the vertical bounds of the foreground across a binary image.
+
+ Smoothing is achieved by removing sharp indents from the polylines
+ vertically bounding the foreground across the width of the image.
+
+ Args:
+ bin_img: A binary image.
+ upper_lower_xs: The x-coordinates of the uppermost and lowermost
+ foreground pixels across the image.
+ upper_lower_ys: The y-coordinates of the uppermost and lowermost
+ foreground pixels across the image.
+
+ Returns:
+ The smoothed x-coordinates of the uppermost and lowermost foreground
+ pixels across the image and the corresponding smoothed y-coordinates of
+ the uppermost and lowermost foreground pixels across the image.
+ """
+ smthd_upper_lower_xs = upper_lower_xs.copy()
+ smthd_upper_lower_ys = upper_lower_ys.copy()
+ for lower, (xs, ys) in enumerate(zip(upper_lower_xs, upper_lower_ys)):
+ # convert outline to signal with peaks and use non-peaks as new
+ # outline
+ if lower:
+ if len(np.unique(ys)) == 1:
+ continue
+ polyline = np.array([[x, y] for x, y in zip(xs, ys)])
+ polyline = cv2.convexHull(polyline)
+ smthd_xs = polyline[..., 0].flatten()
+ smthd_ys = polyline[..., 1].flatten()
+ else:
+ signal = ys if lower else bin_img.shape[0] - ys
+ if not (smthd_xs := find_peaks(signal)[0]).size: # no peaks
+ continue
+ smthd_ys = np.take(ys, smthd_xs)
+
+ # add first and last boundary coordinates again if removed
+ if smthd_xs[0] != xs[0]:
+ smthd_xs = np.insert(smthd_xs, 0, xs[0])
+ smthd_ys = np.insert(smthd_ys, 0, ys[0])
+
+ if smthd_xs[-1] != xs[-1]:
+ smthd_xs = np.insert(smthd_xs, smthd_xs.shape[0], xs[-1])
+ smthd_ys = np.insert(smthd_ys, smthd_ys.shape[0], ys[-1])
+
+ smthd_upper_lower_xs[lower] = smthd_xs
+ smthd_upper_lower_ys[lower] = smthd_ys
+
+ smthd_bin_img = bin_img.astype(np.uint8)
+ cnt = bounded_foreground_polyline(smthd_upper_lower_xs,
+ smthd_upper_lower_ys)
+ cv2.drawContours(smthd_bin_img, [cnt], 0, 1, cv2.FILLED)
+
+ return bound_foreground(smthd_bin_img.astype(bool))
+
+
+def segment_polyline_bounded_region(
+ polyline: npt.NDArray[Any],
+ hw: tuple[int, int],
+) -> npt.NDArray[np.bool_]:
+ """Segments all pixels bounded by a closed polyline on a source image.
+
+ Args:
+ polyline: The xy-coordinates, with respect to a source image, of a
+ polyline.
+ hw: The height and width of the source image.
+
+ Returns:
+ A binary image with all pixels bounded by a closed polyline on a source
+ mage segmented.
+ """
+ bin_img = np.zeros(hw)
+
+ return cv2.drawContours(bin_img, [polyline], 0, 1, cv2.FILLED).astype(bool)
+
+
+def segment_region_within_image(
+ img: npt.NDArray[Any],
+ lower_bgr: npt.NDArray[np.int_],
+ upper_bgr: npt.NDArray[np.int_],
+ region: npt.NDArray[np.bool_],
+) -> npt.NDArray[np.bool_]:
+ """Segments a region within an image.
+
+ Converts a colour image to a binary image where pixels, in a specified
+ region within the image, with BGR values between (inclusive) the specified
+ upper and lower bounds are the foreground (with pixel values of 1).
+
+ Args:
+ img: A colour image.
+ lower_bgr: The lower bound of BGR pixel values (all between 0 and 255)
+ to segment.
+ upper_bgr: The upper bound of BGR pixel values (all between 0 and 255)
+ to segment.
+ region A binary image specifying a region within the original image.
+
+ Returns:
+ A binary image where pixels, in a specified region, with the specified
+ values in the original image are the foreground.
+ """
+ # segment all pixels that fall within the bgr bounds in image
+ bin_img = segment_image(img, lower_bgr, upper_bgr)
+ bin_img[~region] = 0 # black out regions outside region
+
+ return bin_img
+
+
+def segment_region_above_polyline(
+ polyline: npt.NDArray[Any],
+ thickness: int,
+ hw: tuple[int, int],
+) -> npt.NDArray[np.bool_]:
+ """Segments the region above an open polyline on a source image.
+
+ The segmented region will have an uppermost boundary that is the same shape
+ as the initial polyline and will be of the specified thickness.
+
+ Args:
+ polyline: The xy-coordinates, with respect to a source image, of a
+ polyline.
+ thickness: The vertical thickness, in pixels, of the segmented region.
+ hw: The height and width of the source image.
+
+ Returns:
+ A binary image with the region above an open polyline on the source
+ image segmented.
+ """
+ # create a closed polyline of the region above the input polyline
+ region_polyline = polyline[::-1].copy()
+ region_polyline[:, 1] -= thickness
+ region_polyline = np.append(polyline, region_polyline, 0)
+
+ # segment region in the closed polyline
+ bin_img = np.zeros(hw)
+
+ return cv2.drawContours(bin_img, [region_polyline], 0, 1,
+ cv2.FILLED).astype(bool)
+
+
+def draw_polyline(
+ img: npt.NDArray[np.uint8],
+ polyline: npt.NDArray[Any],
+ colour: tuple[int, int, int] = (0, 255, 0),
+ thickness: int = 2,
+) -> npt.NDArray[np.uint8]:
+ """Draws a closed polyline on a colour image.
+
+ Args:
+ img: A colour BGR image.
+ polyline: A polyline of xy-coordinates with respect to the image.
+ colour: The BGR colour of the polyline to be drawn.
+ thickness: The thickness of the polyline to be drawn.
+
+ Returns:
+ The colour image with the closed polyline drawn on.
+ """
+ return cv2.polylines(img.copy(), polyline[None, ...], True, colour,
+ thickness)
+
+
+def binary_to_bgr_image(
+ bin_img: npt.NDArray[np.bool_],
+) -> npt.NDArray[np.uint8]:
+ """Converts a binary image to a colour image with 3 channels (BGR).
+
+ Args:
+ bin_img: A binary image.
+
+ Returns:
+ A colour image with 3 channels (BGR).
+ """
+ bgr_img = bin_img.astype(np.uint8) * MAX_PX_VAL
+
+ return cv2.cvtColor(bgr_img, cv2.COLOR_GRAY2BGR).astype(np.uint8)
+
+
+def extract_channel(
+ img: npt.NDArray[np.uint8],
+ flag: ImageChannel,
+) -> npt.NDArray[np.uint8]:
+ """Extracts the chosen colour channel from an image.
+
+ Args:
+ img: A colour image.
+ flag: A flag that can take values of ImageChannel.
+
+ Returns:
+ A 2D image of the extracted channel.
+ """
+ return cv2.split(img)[flag.value - 1]
+
+
+def auto_segment_image(img: npt.NDArray[np.uint8]) -> npt.NDArray[np.bool_]:
+ """Automatically segments the foreground in a greyscale image.
+
+ Args:
+ img: A greyscale image.
+
+ Returns:
+ A binary image of the segmented foreground from the input image.
+ """
+ img = cv2.medianBlur(~img, KSIZE)
+ bin_img = cv2.adaptiveThreshold(img, MAX_PX_VAL,
+ cv2.ADAPTIVE_THRESH_MEAN_C,
+ cv2.THRESH_BINARY, BLOCKSIZE, C)
+
+ return ~(bin_img / MAX_PX_VAL).astype(bool)
+
+
+def detect_circular_objects(
+ img: npt.NDArray[np.uint8],
+ min_dist: int = 12,
+ alpha: int = 10,
+ beta: int = 14,
+ min_radius: int = 5,
+ max_radius: int = 15,
+ min_obj_area: int = 20,
+ bgd_px_thresh: int = 20,
+) -> list[npt.NDArray[Any]]:
+ """Detects circular objects in an image.
+
+ Args:
+ img: A greyscale image.
+ min_dist: The minimum distance between the centers of the circular
+ objects in pixels.
+ alpha: A parameter that can be fine tuned for circular object
+ detection performance. It may be decreased to detect more objects.
+ beta: A parameter that can be fine tuned for circular object
+ detection performance. The smaller it is, the more false objects
+ may be detected.
+ min_radius: The minimum radii of circular objects in pixels.
+ max_radius: The maximum radii of circular objects in pixels.
+ min_obj_area: The minimum area of circular objects.
+ bgd_px_thresh: The maximum value of background pixels in the image.
+
+ Returns:
+ A sequence of coordinates for circular objects detected in the image.
+ """
+ img = cv2.medianBlur(img, KSIZE)
+ circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, DP, min_dist,
+ param1=alpha, param2=beta, minRadius=min_radius,
+ maxRadius=max_radius)
+ objs = []
+ if circles is not None:
+ circles = np.uint16(np.around(circles))
+ for c in circles[0, :]:
+ mask = np.ones(img.shape)
+ cv2.circle(mask, (c[0], c[1]), c[2], 0, cv2.FILLED)
+ mask = mask.astype(bool)
+ roi = img.copy()
+ roi[mask] = 0
+ roi[roi > bgd_px_thresh] = 255
+ roi[roi <= bgd_px_thresh] = 0
+ cts, _ = cv2.findContours(roi.astype(np.uint8), cv2.RETR_LIST,
+ cv2.CHAIN_APPROX_NONE)
+ objs += [ct for ct in cts if cv2.contourArea(ct) > min_obj_area]
+
+ return objs
+
+
+def centre_coordinates(contours: list[npt.NDArray[Any]]) -> npt.NDArray[Any]:
+ """Gets the x and y coordinates of the centres of the provided contours.
+
+ Args:
+ contours: A sequence of contours where each contour is an array of
+ x and y coordinates.
+
+ Returns:
+ A sequence of the x and y coordinates of the centres of the respective
+ input contours.
+ """
+ centres = []
+ for c in contours:
+ m = cv2.moments(c)
+ x = int(m['m10'] / m['m00'])
+ y = int(m['m01'] / m['m00'])
+ centres.append((x, y))
+
+ return np.array(centres)
+
+
+def subimage_coordinates(
+ img: npt.NDArray[Any],
+ background_bgr: tuple[int, int, int] = (255, 255, 255),
+) -> npt.NDArray[Any]:
+ """Finds the coordinates of sub-images in a larger image.
+
+ Args:
+ img: A colour image.
+ background_bgr: The BGR value of background pixels in the larger image.
+
+ Returns:
+ An array of the (x1, y1, x2, y2) coordinates of the bounding boxes for
+ all sub-images in the larger image.
+ """
+ bin_img = ~segment_image(img, np.array(background_bgr),
+ np.array(background_bgr))
+ contours, _ = cv2.findContours(bin_img.astype(np.uint8), cv2.RETR_EXTERNAL,
+ cv2.CHAIN_APPROX_SIMPLE)
+
+ coords = []
+ for c in contours:
+ x1, x2 = c[:, 0, 0].min(), c[:, 0, 0].max()
+ y1, y2 = c[:, 0, 1].min(), c[:, 0, 1].max()
+ coords.append((x1, y1, x2, y2))
+
+ return np.array(coords)
+
+
+def largest_objects(
+ bin_img: npt.NDArray[np.bool_],
+ min_area: int | None = None,
+ top_n: int | None = None,
+) -> tuple[list[list[npt.NDArray[Any]]], list[list[npt.NDArray[Any]]]]:
+ """Finds the contours of the largest foreground objects in a binary image.
+
+ Large objects are those with at least the given area and/or those that are
+ the top n largest objects in the image.
+
+ Args:
+ bin_img: A binary image.
+ min_area: The minimum object area.
+ top_n: The top number of largest objects to find.
+
+ Returns:
+ The contours of the largest foreground objects in the input image as a
+ sequence of x-coordinates for the upper object boundary(s) across the
+ width of the image and the corresponding y-coordinates of lower object
+ boundary(s) across the image
+ """
+ cnts, _ = cv2.findContours(bin_img.astype(np.uint8), cv2.RETR_LIST,
+ cv2.CHAIN_APPROX_NONE)
+
+ if min_area is not None:
+ cnts = [c for c in cnts if cv2.contourArea(c) >= min_area]
+ if top_n is not None:
+ cnts = sorted(cnts, key=lambda c: cv2.contourArea(c),
+ reverse=True)[:top_n]
+
+ upper_lower_xs, upper_lower_ys = [], []
+ for c in cnts:
+ l, r = c[..., 0].argmin(), c[..., 0].argmax()
+ if l > r:
+ l, r, c = len(c) - l, len(c) - r, c[::-1]
+ l_xs, l_ys = c[l:r + 1][..., 0][:, 0], c[l:r + 1][..., 1][:, 0]
+ u_xs_ys = np.append(c[0:l][::-1], c[r + 1:][::-1], 0)
+ u_xs, u_ys = u_xs_ys[..., 0][:, 0], u_xs_ys[..., 1][:, 0]
+ upper_lower_xs.append([u_xs, l_xs])
+ upper_lower_ys.append([u_ys, l_ys])
+
+ return upper_lower_xs, upper_lower_ys
diff --git a/bimana/utils/quantification.py b/bimana/utils/quantification.py
new file mode 100644
index 0000000..62718e0
--- /dev/null
+++ b/bimana/utils/quantification.py
@@ -0,0 +1,221 @@
+import re
+from math import pi, sqrt
+from pathlib import Path
+from typing import Any
+
+import cv2
+import matplotlib.pyplot as plt
+import numpy as np
+import numpy.typing as npt
+import pandas as pd
+from scipy.spatial import KDTree
+from scipy.stats import describe
+
+
+def percentage_foreground_in_region(
+ img: npt.NDArray[np.bool_],
+ region: npt.NDArray[np.bool_],
+) -> tuple[float, int, int]:
+ """Finds the percentage of a region occupied by the foreground in an image.
+
+ Args:
+ img: A binary image representing the primary image.
+ region: A binary image specifying a region within the primary image.
+
+ Returns:
+ The percentage of the specified region within the primary image
+ occupied by the foreground as well as the size of the corresponding
+ foreground and region in pixels.
+ """
+ img = img.copy()
+ img[~region] = 0
+ foreground_count = np.count_nonzero(img)
+ region_count = np.count_nonzero(region)
+ pct = round(foreground_count / region_count * 100, 2)
+
+ return pct, foreground_count, region_count
+
+
+def nearest_neighbour_distances(
+ pts: npt.NDArray[Any],
+) -> npt.NDArray[np.float_]:
+ """Finds the nearest neighbor distances for a given set of 2D points.
+
+ Args:
+ pts: An array of x and y coordinates for a set of 2D points.
+
+ Returns:
+ A sequence of distances, in pixels, corresponding to each input point's
+ nearest neighbor.
+ """
+ tree = KDTree(pts)
+ dists, _ = tree.query(pts, 2)
+
+ return dists[:, 1]
+
+
+def area(contours: list[npt.NDArray[Any]]) -> list[float]:
+ """Calculates the area enclosed by each given contour.
+
+ Args:
+ contours: A sequence of contours each as an array of x and y
+ coordinates.
+
+ Returns:
+ The areas enclosed by the given contours in pixels.
+ """
+ return [cv2.contourArea(c) for c in contours]
+
+
+def perimeter(contours: list[npt.NDArray[Any]]) -> list[float]:
+ """Calculates the perimeter of each given contour.
+
+ Args:
+ contours: A sequence of contours each as an array of x and y
+ coordinates.
+
+ Returns:
+ The perimeters of the given contours in pixels.
+ """
+ return [cv2.arcLength(c, True) for c in contours]
+
+
+def circularity(contours: list[npt.NDArray[Any]]) -> list[float]:
+ """Calculates the circularity of each given contour.
+
+ Args:
+ contours: A sequence of contours each as an array of x and y
+ coordinates.
+
+ Returns:
+ The circularities of the given contours.
+ """
+ return [(4 * pi * area([c])[0]) / perimeter([c])[0]**2 for c in contours]
+
+
+def aspect_ratio(contours: list[npt.NDArray[Any]]) -> list[float]:
+ """Calculates the aspect ratio of each given contour.
+
+ Args:
+ contours: A sequence of contours each as an array of x and y
+ coordinates.
+
+ Returns:
+ The aspect ratios of the given contours.
+ """
+ aspect_ratios = []
+ for c in contours:
+ _, _, w, h = cv2.boundingRect(c)
+ aspect_ratios.append(float(w) / h)
+
+ return aspect_ratios
+
+
+def solidity(contours: list[npt.NDArray[Any]]) -> list[float]:
+ """Calculates the solidity of each given contour.
+
+ Args:
+ contours: A sequence of contours each as an array of x and y
+ coordinates.
+
+ Returns:
+ The solidities of the given contours.
+ """
+ solidities = []
+ for c in contours:
+ area = cv2.contourArea(c)
+ hull = cv2.convexHull(c)
+ hull_area = cv2.contourArea(hull)
+ solidities.append(float(area) / hull_area)
+
+ return solidities
+
+
+def roundness(contours: list[npt.NDArray[Any]]) -> list[float]:
+ """Calculates the roundness of each given contour.
+
+ Args:
+ contours: A sequence of contours each as an array of x and y
+ coordinates.
+
+ Returns:
+ The roundness values of the given contours.
+ """
+ roundness_vals = []
+ for c in contours:
+ h = cv2.boundingRect(c)[3]
+ area = cv2.contourArea(c)
+ roundness_vals.append((4 * area) / (pi * h**2))
+
+ return roundness_vals
+
+
+def num_connected_components(img: npt.NDArray[np.bool_]) -> int:
+ """Finds the number of connected foreground regions in a binary image.
+
+ Args:
+ img: A binary image.
+
+ Returns:
+ The number of connected foreground regions in the input binary image.
+ """
+ return cv2.connectedComponents(img.astype(np.uint8))[0] - 1
+
+
+def size_connected_components(img: npt.NDArray[np.bool_]) -> npt.NDArray[Any]:
+ """Finds the size of each connected foreground region in a binary image.
+
+ Args:
+ img: A binary image.
+
+ Returns:
+ The sizes, in pixels, of all connected foreground regions in the binary
+ image.
+ """
+ stats = cv2.connectedComponentsWithStats(img.astype(np.uint8))[2]
+
+ return stats[1:, cv2.CC_STAT_AREA]
+
+
+def gen_stats(metric: list[Any] | npt.NDArray[Any]) -> dict[str, Any]:
+ """Calculates statistics for a given metric.
+
+ The statistics are the minimum value, maximum value, mean, standard
+ deviation and variance.
+
+ Args:
+ metric: A sequence of values for a given metric.
+
+ Returns:
+ The statistics for the given metric.
+ """
+ stats = describe(metric, nan_policy='omit')
+
+ return {'Min': stats[1][0], 'Max': stats[1][1], 'Mean (μ)': stats[2],
+ 'STD (σ)': sqrt(stats[3]), 'Var (σ²)': stats[3]}
+
+
+def gen_histogram(
+ data: dict[str, Any],
+ output_dir: Path,
+ dpi: int = 300,
+) -> None:
+ """Generates a histogram of the input data in the output directory.
+
+ Args:
+ data: A dictionary of the data values and the name of the corresponding
+ metric.
+ output_dir: The output directory.
+ dpi: The DPI of the histogram.
+ """
+ df = pd.DataFrame(data)
+ ax = df.hist()[0][0]
+ name = list(data.keys())[0]
+ ax.set_title(' '.join((re.sub(
+ r'\(.*\)', '', name) + ' Histogram').split()))
+ ax.set_xlabel(name)
+ ax.set_ylabel('Frequency')
+ output_path = output_dir / (' '.join((re.sub(
+ r'\(.*\)', '', name) + ' histogram').split())).lower()
+ ax.get_figure().savefig(output_path, dpi=dpi)
+ plt.close()
diff --git a/misc/checkpoints/DexiNed/BIPED/10/10_model.pth b/misc/checkpoints/DexiNed/BIPED/10/10_model.pth
new file mode 100644
index 0000000..2f6e1b8
--- /dev/null
+++ b/misc/checkpoints/DexiNed/BIPED/10/10_model.pth
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bd4c603ef71113b447bffb72a73b9a54ca890e78f4bc8f34cb73f1efb2681e74
+size 141069187
diff --git a/misc/examples/histological_section/1.tif b/misc/examples/histological_section/1.tif
new file mode 100644
index 0000000..f9c610e
Binary files /dev/null and b/misc/examples/histological_section/1.tif differ
diff --git a/misc/examples/histological_section/1_tif/binary_image.png b/misc/examples/histological_section/1_tif/binary_image.png
new file mode 100644
index 0000000..915d9e3
Binary files /dev/null and b/misc/examples/histological_section/1_tif/binary_image.png differ
diff --git a/misc/examples/histological_section/1_tif/binary_image_without_isolated_non_tissue.png b/misc/examples/histological_section/1_tif/binary_image_without_isolated_non_tissue.png
new file mode 100644
index 0000000..2467c1d
Binary files /dev/null and b/misc/examples/histological_section/1_tif/binary_image_without_isolated_non_tissue.png differ
diff --git a/misc/examples/histological_section/1_tif/cilia_above_tissue_area.png b/misc/examples/histological_section/1_tif/cilia_above_tissue_area.png
new file mode 100644
index 0000000..5ba060f
Binary files /dev/null and b/misc/examples/histological_section/1_tif/cilia_above_tissue_area.png differ
diff --git a/misc/examples/histological_section/1_tif/raw_tissue_boundary.png b/misc/examples/histological_section/1_tif/raw_tissue_boundary.png
new file mode 100644
index 0000000..f6f0972
Binary files /dev/null and b/misc/examples/histological_section/1_tif/raw_tissue_boundary.png differ
diff --git a/misc/examples/histological_section/1_tif/segmented_tissue.png b/misc/examples/histological_section/1_tif/segmented_tissue.png
new file mode 100644
index 0000000..efddc8f
Binary files /dev/null and b/misc/examples/histological_section/1_tif/segmented_tissue.png differ
diff --git a/misc/examples/histological_section/1_tif/smoothed_tissue_boundary.png b/misc/examples/histological_section/1_tif/smoothed_tissue_boundary.png
new file mode 100644
index 0000000..50e64b1
Binary files /dev/null and b/misc/examples/histological_section/1_tif/smoothed_tissue_boundary.png differ
diff --git a/misc/examples/histological_section/1_tif/staining_within_tissue_boundary.png b/misc/examples/histological_section/1_tif/staining_within_tissue_boundary.png
new file mode 100644
index 0000000..f0502a4
Binary files /dev/null and b/misc/examples/histological_section/1_tif/staining_within_tissue_boundary.png differ
diff --git a/misc/examples/histological_section/1_tif/tissue_boundary_on_original.png b/misc/examples/histological_section/1_tif/tissue_boundary_on_original.png
new file mode 100644
index 0000000..78a167f
Binary files /dev/null and b/misc/examples/histological_section/1_tif/tissue_boundary_on_original.png differ
diff --git a/misc/examples/histological_section/metrics.csv b/misc/examples/histological_section/metrics.csv
new file mode 100644
index 0000000..19a892f
--- /dev/null
+++ b/misc/examples/histological_section/metrics.csv
@@ -0,0 +1,2 @@
+Image,File path,Amount of staining (no. pixels),Tissue area size (no. pixels),Percentage of staining in tissue area (%),Amount of cilia (no. pixels),Cilia-containing region size (no. pixels),Percentage of region occupied by cilia (%)
+1.tif,C:\Users\Alphons\Downloads\1.tif,4678,29714,15.74,1560,5670,27.51
diff --git a/misc/examples/live_cell_imaging/raw_metrics.txt b/misc/examples/live_cell_imaging/raw_metrics.txt
new file mode 100644
index 0000000..bc5f6b8
--- /dev/null
+++ b/misc/examples/live_cell_imaging/raw_metrics.txt
@@ -0,0 +1,12 @@
+Vessel Name: 220727_2%FCS_X_C55_C56_C57_C58
+Metric: Relative Wound Density (%)
+Cell Type: X
+Passage: 24
+Notes: C55_C56_C57_C58
+Analysis: X_Wounding_CS_V2
+
+Date Time Elapsed CA 10 µM (A1) CA 10 µM (A2) CA 10 µM (A3) CA 10 µM (A4) CA 10 µM (A5) CC 10 µM (A6) CC 10 µM (A7) CC 10 µM (A8) CC 10 µM (A9) CC 10 µM (A10) DMSO 0.05% (A11) DMSO 0.05% (B11) DMSO 0.05% (C11) DMSO 0.05% (D11) DMSO 0.05% (E11) DMSO 0.05% (F11) UT 100% (A12) UT 100% (B12) UT 100% (C12) UT 100% (D12) UT 100% (E12) UT 100% (F12) CA 1 µM (B1) CA 1 µM (B2) CA 1 µM (B3) CA 1 µM (B4) CA 1 µM (B5) CC 1 µM (B6) CC 1 µM (B7) CC 1 µM (B8) CC 1 µM (B9) CC 1 µM (B10) CA 0.1 µM (C1) CA 0.1 µM (C2) CA 0.1 µM (C3) CA 0.1 µM (C4) CA 0.1 µM (C5) CC 0.1 µM (C6) CC 0.1 µM (C7) CC 0.1 µM (C8) CC 0.1 µM (C9) CC 0.1 µM (C10) CA 0.01 µM (D1) CA 0.01 µM (D2) CA 0.01 µM (D3) CA 0.01 µM (D4) CA 0.01 µM (D5) CC 0.01 µM (D6) CC 0.01 µM (D7) CC 0.01 µM (D8) CC 0.01 µM (D9) CC 0.01 µM (D10) CB 10 µM (E1) CB 10 µM (E2) CB 10 µM (E3) CB 10 µM (E4) CB 10 µM (E5) CD 10 µM (E6) CD 10 µM (E7) CD 10 µM (E8) CD 10 µM (E9) CD 10 µM (E10) CB 1 µM (F1) CB 1 µM (F2) CB 1 µM (F3) CB 1 µM (F4) CB 1 µM (F5) CD 1 µM (F6) CD 1 µM (F7) CD 1 µM (F8) CD 1 µM (F9) CD 1 µM (F10) CB 0.1 µM (G1) CB 0.1 µM (G2) CB 0.1 µM (G3) CB 0.1 µM (G4) CB 0.1 µM (G5) CD 0.1 µM (G6) CD 0.1 µM (G7) CD 0.1 µM (G8) CD 0.1 µM (G9) CD 0.1 µM (G10) Pos 10 µM (G11) Pos 10 µM (G12) Pos 10 µM (H11) Pos 10 µM (H12) CB 0.01 µM (H1) CB 0.01 µM (H2) CB 0.01 µM (H3) CB 0.01 µM (H4) CB 0.01 µM (H5) CD 0.01 µM (H6) CD 0.01 µM (H7) CD 0.01 µM (H8) CD 0.01 µM (H9) CD 0.01 µM (H10)
+27/07/2022 18:00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+27/07/2022 21:00 3 2.941424 0.7709512 -0.9661244 1.2095 1.907017 1.891028 1.445611 2.349506 1.624458 1.587884 2.080587 1.17492 0.4584868 0.849259 2.211427 3.804555 2.52322 1.118516 1.60945 2.483132 2.296167 0 0 1.857243 2.125729 2.373146 1.194392 0.8878424 -0.1615143 0.6991959 0.5156834 5.149718 0.6990805 0.9538784 0.6376827 0.8849707 1.343013 0.3406399 1.909729 1.011549 -0.3114207 1.171259 0.5547474 1.48487 0.1732116 0 0.4102185 0.778515 1.776656 0.1189434 0.7330513 0.4719042 0.7252991 0.4734694 0.8170961 2.897962 0.5366114 0.4626927 3.35836 1.302759 2.761429 1.018728 1.988602 1.417326 1.585365 2.739432 4.537059 1.258467 0.985615 1.610166 3.046306 3.7115 1.443673 0.8639878 1.5654 3.624008 5.149839 3.571585 7.690483 3.238868 3.952368 3.987249 3.654827 3.378263 3.771674 2.597566 3.637967 3.37047 3.792182 3.945292
+28/07/2022 0:00 6 3.439121 1.6205 0.08946762 3.070065 4.391799 3.2835 2.698675 3.589451 2.745719 2.628779 4.241597 2.058636 0.5669807 1.397869 3.886579 6.691884 4.031245 3.079788 1.979 3.509718 3.066563 0 0 3.644812 3.306175 3.838465 2.640489 3.025772 0.1791517 1.056791 1.143308 7.459068 1.061978 1.937168 1.175532 2.306213 2.372698 1.178732 3.314485 1.402258 0.9818405 2.02676 1.598561 2.414337 1.259886 0 1.62955 1.222111 2.608018 1.932287 1.126612 2.181001 1.848864 1.295691 1.538294 3.932674 1.358594 0.4188254 5.386405 2.583961 5.516322 2.459945 3.861227 3.130836 2.664682 4.383809 6.429445 3.61166 3.107372 2.625817 4.931927 6.191323 3.711043 3.307125 2.791503 4.252559 8.501356 6.001993 10.31227 6.180362 5.806409 5.472285 6.167523 4.483469 1.760216 5.003536 5.636861 4.774235 5.645293 -2.221393
+28/07/2022 3:00 9 3.740245 2.080393 0.2708296 4.446393 6.11115 5.104506 4.735899 4.781292 4.02871 4.009587 5.759967 3.06436 1.229087 2.486529 5.615928 9.599972 5.95135 4.018443 3.028037 4.631933 4.058403 0 0 5.471172 4.179026 5.418031 4.278059 4.051464 0.3846287 1.295455 1.604261 9.598935 1.321902 2.699774 1.478293 2.644482 2.847978 1.885295 4.702738 1.804498 1.61727 2.03718 2.726338 3.53512 2.024735 0 2.289491 1.925745 4.000076 3.506441 1.503308 2.33948 2.698667 2.474415 2.4721 5.882982 1.669194 0.874815 9.470068 3.560443 8.033844 2.890385 5.567244 4.630435 3.837245 6.945757 10.9377 5.78016 4.265481 5.388308 7.160444 9.596511 5.696442 5.794175 4.79989 7.638964 12.92765 8.235493 13.48496 8.211935 9.269642 10.3357 10.07243 8.349841 4.832891 8.941649 9.623076 10.47854 10.13736 2.531106
diff --git a/misc/examples/live_cell_imaging/raw_metrics_txt/C55_wound_closure.png b/misc/examples/live_cell_imaging/raw_metrics_txt/C55_wound_closure.png
new file mode 100644
index 0000000..6912750
Binary files /dev/null and b/misc/examples/live_cell_imaging/raw_metrics_txt/C55_wound_closure.png differ
diff --git a/misc/examples/live_cell_imaging/raw_metrics_txt/C56_wound_closure.png b/misc/examples/live_cell_imaging/raw_metrics_txt/C56_wound_closure.png
new file mode 100644
index 0000000..b610a1f
Binary files /dev/null and b/misc/examples/live_cell_imaging/raw_metrics_txt/C56_wound_closure.png differ
diff --git a/misc/examples/live_cell_imaging/raw_metrics_txt/C57_wound_closure.png b/misc/examples/live_cell_imaging/raw_metrics_txt/C57_wound_closure.png
new file mode 100644
index 0000000..3822902
Binary files /dev/null and b/misc/examples/live_cell_imaging/raw_metrics_txt/C57_wound_closure.png differ
diff --git a/misc/examples/live_cell_imaging/raw_metrics_txt/C58_wound_closure.png b/misc/examples/live_cell_imaging/raw_metrics_txt/C58_wound_closure.png
new file mode 100644
index 0000000..090a855
Binary files /dev/null and b/misc/examples/live_cell_imaging/raw_metrics_txt/C58_wound_closure.png differ
diff --git a/misc/examples/live_cell_imaging/raw_metrics_txt/raw_metrics_analysed.xlsx b/misc/examples/live_cell_imaging/raw_metrics_txt/raw_metrics_analysed.xlsx
new file mode 100644
index 0000000..a3d2371
Binary files /dev/null and b/misc/examples/live_cell_imaging/raw_metrics_txt/raw_metrics_analysed.xlsx differ
diff --git a/misc/examples/tight_junctions/1.tif b/misc/examples/tight_junctions/1.tif
new file mode 100644
index 0000000..b39eca6
Binary files /dev/null and b/misc/examples/tight_junctions/1.tif differ
diff --git a/misc/examples/tight_junctions/1_tif/cell area histogram.png b/misc/examples/tight_junctions/1_tif/cell area histogram.png
new file mode 100644
index 0000000..a75d301
Binary files /dev/null and b/misc/examples/tight_junctions/1_tif/cell area histogram.png differ
diff --git a/misc/examples/tight_junctions/1_tif/cell aspect ratio histogram.png b/misc/examples/tight_junctions/1_tif/cell aspect ratio histogram.png
new file mode 100644
index 0000000..106ff1d
Binary files /dev/null and b/misc/examples/tight_junctions/1_tif/cell aspect ratio histogram.png differ
diff --git a/misc/examples/tight_junctions/1_tif/cell circularity histogram.png b/misc/examples/tight_junctions/1_tif/cell circularity histogram.png
new file mode 100644
index 0000000..a77b55e
Binary files /dev/null and b/misc/examples/tight_junctions/1_tif/cell circularity histogram.png differ
diff --git a/misc/examples/tight_junctions/1_tif/cell image channel.png b/misc/examples/tight_junctions/1_tif/cell image channel.png
new file mode 100644
index 0000000..6ca0316
Binary files /dev/null and b/misc/examples/tight_junctions/1_tif/cell image channel.png differ
diff --git a/misc/examples/tight_junctions/1_tif/cell perimeter histogram.png b/misc/examples/tight_junctions/1_tif/cell perimeter histogram.png
new file mode 100644
index 0000000..75bfee5
Binary files /dev/null and b/misc/examples/tight_junctions/1_tif/cell perimeter histogram.png differ
diff --git a/misc/examples/tight_junctions/1_tif/cell roundness histogram.png b/misc/examples/tight_junctions/1_tif/cell roundness histogram.png
new file mode 100644
index 0000000..9b40a0d
Binary files /dev/null and b/misc/examples/tight_junctions/1_tif/cell roundness histogram.png differ
diff --git a/misc/examples/tight_junctions/1_tif/cell solidity histogram.png b/misc/examples/tight_junctions/1_tif/cell solidity histogram.png
new file mode 100644
index 0000000..d5468f6
Binary files /dev/null and b/misc/examples/tight_junctions/1_tif/cell solidity histogram.png differ
diff --git a/misc/examples/tight_junctions/1_tif/cells.png b/misc/examples/tight_junctions/1_tif/cells.png
new file mode 100644
index 0000000..b70be1c
Binary files /dev/null and b/misc/examples/tight_junctions/1_tif/cells.png differ
diff --git a/misc/examples/tight_junctions/1_tif/tight junction fragment size histogram.png b/misc/examples/tight_junctions/1_tif/tight junction fragment size histogram.png
new file mode 100644
index 0000000..4fc011b
Binary files /dev/null and b/misc/examples/tight_junctions/1_tif/tight junction fragment size histogram.png differ
diff --git a/misc/examples/tight_junctions/1_tif/tight junction pixel intensity histogram.png b/misc/examples/tight_junctions/1_tif/tight junction pixel intensity histogram.png
new file mode 100644
index 0000000..58a46ba
Binary files /dev/null and b/misc/examples/tight_junctions/1_tif/tight junction pixel intensity histogram.png differ
diff --git a/misc/examples/tight_junctions/1_tif/tight junctions binary mask.png b/misc/examples/tight_junctions/1_tif/tight junctions binary mask.png
new file mode 100644
index 0000000..c9e1c93
Binary files /dev/null and b/misc/examples/tight_junctions/1_tif/tight junctions binary mask.png differ
diff --git a/misc/examples/tight_junctions/1_tif/tight junctions detected edges.png b/misc/examples/tight_junctions/1_tif/tight junctions detected edges.png
new file mode 100644
index 0000000..16594a1
Binary files /dev/null and b/misc/examples/tight_junctions/1_tif/tight junctions detected edges.png differ
diff --git a/misc/examples/tight_junctions/1_tif/tight junctions image channel.png b/misc/examples/tight_junctions/1_tif/tight junctions image channel.png
new file mode 100644
index 0000000..05c4ab5
Binary files /dev/null and b/misc/examples/tight_junctions/1_tif/tight junctions image channel.png differ
diff --git a/misc/examples/tight_junctions/1_tif/tight junctions.png b/misc/examples/tight_junctions/1_tif/tight junctions.png
new file mode 100644
index 0000000..c98a5ae
Binary files /dev/null and b/misc/examples/tight_junctions/1_tif/tight junctions.png differ
diff --git a/misc/examples/tight_junctions/metrics.csv b/misc/examples/tight_junctions/metrics.csv
new file mode 100644
index 0000000..bbe27e5
--- /dev/null
+++ b/misc/examples/tight_junctions/metrics.csv
@@ -0,0 +1,2 @@
+Image,File path,Tight Junction Pixel Intensity (%) (Min),Tight Junction Pixel Intensity (%) (Max),Tight Junction Pixel Intensity (%) (Mean (μ)),Tight Junction Pixel Intensity (%) (STD (σ)),Tight Junction Pixel Intensity (%) (Var (σ²)),Intercellular Junction Organization Quantification (AU),Number of Tight Junction Fragments,Tight Junction Fragment Size (No. Pixels) (Min),Tight Junction Fragment Size (No. Pixels) (Max),Tight Junction Fragment Size (No. Pixels) (Mean (μ)),Tight Junction Fragment Size (No. Pixels) (STD (σ)),Tight Junction Fragment Size (No. Pixels) (Var (σ²)),Number of Cells,Cell Area (No. Pixels) (Min),Cell Area (No. Pixels) (Max),Cell Area (No. Pixels) (Mean (μ)),Cell Area (No. Pixels) (STD (σ)),Cell Area (No. Pixels) (Var (σ²)),Cell Aspect Ratio (AU) (Min),Cell Aspect Ratio (AU) (Max),Cell Aspect Ratio (AU) (Mean (μ)),Cell Aspect Ratio (AU) (STD (σ)),Cell Aspect Ratio (AU) (Var (σ²)),Cell Circularity (AU) (Min),Cell Circularity (AU) (Max),Cell Circularity (AU) (Mean (μ)),Cell Circularity (AU) (STD (σ)),Cell Circularity (AU) (Var (σ²)),Cell Perimeter (No. Pixels) (Min),Cell Perimeter (No. Pixels) (Max),Cell Perimeter (No. Pixels) (Mean (μ)),Cell Perimeter (No. Pixels) (STD (σ)),Cell Perimeter (No. Pixels) (Var (σ²)),Cell Roundness (AU) (Min),Cell Roundness (AU) (Max),Cell Roundness (AU) (Mean (μ)),Cell Roundness (AU) (STD (σ)),Cell Roundness (AU) (Var (σ²)),Cell Solidity (AU) (Min),Cell Solidity (AU) (Max),Cell Solidity (AU) (Mean (μ)),Cell Solidity (AU) (STD (σ)),Cell Solidity (AU) (Var (σ²))
+1.tif,C:\Users\Alphons\Downloads\1.tif,2.352941176,64.31372549,10.58486385,3.777406814,14.26880224,0.0316,237,1,569139,3313.814346,37099.5823,1376379007,1155,21,539.5,192.0701299,63.61895284,4047.371161,0.388888889,2.363636364,1.005597437,0.122970569,0.015121761,0.218970874,0.91158714,0.807122727,0.088109426,0.007763271,18.14213538,125.3969686,54.13620931,10.08855439,101.7789297,0.185680767,1.650495706,0.794863641,0.116382597,0.013544909,0.47,1,0.938037024,0.042486265,0.001805083
diff --git a/misc/images/bimana.png b/misc/images/bimana.png
new file mode 100644
index 0000000..8ec71b8
Binary files /dev/null and b/misc/images/bimana.png differ
diff --git a/misc/images/pytorch_get_started.png b/misc/images/pytorch_get_started.png
new file mode 100644
index 0000000..d5f4045
Binary files /dev/null and b/misc/images/pytorch_get_started.png differ
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..a021f8b
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,41 @@
+[build-system]
+requires = ["setuptools>=64"]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "bimana"
+description = "Package for performing automated bio-image analysis tasks."
+readme = "README.md"
+authors = [
+ {name = "Alphons Gwatimba"},
+ {email = "0go0vdp95@mozmail.com"}
+]
+requires-python = ">=3.10"
+license = {file = "LICENSE"}
+version = "0.1.0"
+dependencies = [
+ "natsort",
+ "click-web",
+ "scipy",
+ "opencv-python",
+ "pandas",
+ "pyvips",
+ "matplotlib",
+ "kornia",
+ 'xlsxwriter',
+ 'openpyxl',
+]
+
+[project.urls]
+homepage = "https://github.com/AlphonsG/BIMANA"
+documentation = "https://github.com/AlphonsG/BIMANA"
+repository = "https://github.com/AlphonsG/BIMANA"
+
+[project.optional-dependencies]
+test = ['pytest', 'pytest-cov', 'flake8']
+
+[project.scripts]
+bimana = "bimana.__main__:main"
+
+[tool.setuptools]
+packages = ["bimana"]
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..25242e3
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,47 @@
+attrs==22.1.0
+certifi==2022.9.24
+cffi==1.15.1
+charset-normalizer==2.1.1
+click==8.1.3
+click-web==0.8.0
+colorama==0.4.6
+contourpy==1.0.6
+coverage==6.5.0
+cycler==0.11.0
+exceptiongroup==1.0.4
+Flask==2.2.2
+Flask-HTTPAuth==4.7.0
+fonttools==4.38.0
+idna==3.4
+iniconfig==1.1.1
+itsdangerous==2.1.2
+Jinja2==3.1.2
+kiwisolver==1.4.4
+kornia==0.6.8
+MarkupSafe==2.1.1
+matplotlib==3.6.2
+natsort==8.2.0
+numpy==1.23.5
+opencv-python==4.6.0.66
+packaging==21.3
+pandas==1.5.2
+Pillow==9.3.0
+pluggy==1.0.0
+pycparser==2.21
+pyparsing==3.0.9
+pytest==7.2.0
+pytest-cov==4.0.0
+python-dateutil==2.8.2
+pytz==2022.6
+pyvips==2.2.1
+requests==2.28.1
+scipy==1.9.3
+six==1.16.0
+tomli==2.0.1
+torch==1.13.0
+torchaudio==0.13.0
+torchvision==0.14.0
+typing_extensions==4.4.0
+urllib3==1.26.13
+Werkzeug==2.2.2
+wheel==0.38.4
\ No newline at end of file
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..da96bd5
--- /dev/null
+++ b/tests/__init__.py
@@ -0,0 +1,30 @@
+from pathlib import Path
+
+DATA_DIR = Path(__file__).parent.resolve() / 'data'
+
+TEST_IMG_PTH = str(DATA_DIR / 'image.tif')
+TEST_BIN_IMG_PTH = str(DATA_DIR / 'binary_image.tif')
+TEST_REF_BIN_IMG_PTH = str(DATA_DIR / 'cropped_refined_binary_image.tif')
+TEST_TISS_BNDY_PTH = str(DATA_DIR / 'tissue_boundary.pickle')
+ROOT_DIR_PTH = DATA_DIR / str('root_directory')
+HIST_SECT_IMG_DIR_PTH = str(DATA_DIR / 'histological_section/images')
+LENA_IMG_PTH = str(DATA_DIR / 'lena.tif')
+GREYSCALE_IMG_PTH = str(DATA_DIR / 'greyscale_image.jpg')
+BIN_TGHT_JNCS_PTH = str(DATA_DIR / 'binary_tight_junctions.png')
+CIRCLES_IMG_PTH = str(DATA_DIR / 'circles.png')
+TIGHT_JUNCS_IMG_PTH = str(DATA_DIR / 'tight_junctions.tiff')
+SUBIMG_PTH = str(DATA_DIR / 'subimage/subimage.png')
+METRICS_TXT_FILE_PATH = str(DATA_DIR / 'live_cell_imaging/test.txt')
+METRICS_DF_PATH = str(DATA_DIR / 'live_cell_imaging/metrics_df.csv')
+INFO_DF_PATH = str(DATA_DIR / 'live_cell_imaging/info_df.csv')
+TIME_DF_PATH = str(DATA_DIR / 'live_cell_imaging/time_df.csv')
+NOTES_COMPDS_DF_PATH = str(DATA_DIR / 'live_cell_imaging/'
+ 'notes_compounds_df.csv')
+STATS_DF = str(DATA_DIR / 'live_cell_imaging/stats_df.csv')
+CTRL_DF = str(DATA_DIR / 'live_cell_imaging/ctrl_df.csv')
+FLD_CHG_DF = str(DATA_DIR / 'live_cell_imaging/fld_chg_df.csv')
+COMPDS_DF = str(DATA_DIR / 'live_cell_imaging/compds_df.csv')
+FLD_CHG_STATS_DF = str(DATA_DIR / 'live_cell_imaging/fld_chg_stats_df.csv')
+GEND_EXCEL = str(DATA_DIR / 'live_cell_imaging/test.xlsx')
+FIGURES_DIR = str(DATA_DIR / 'live_cell_imaging/figures')
+DFS_PATH = str(DATA_DIR / 'live_cell_imaging/dfs.pickle')
diff --git a/tests/data/binary_image.tif b/tests/data/binary_image.tif
new file mode 100644
index 0000000..6fab217
Binary files /dev/null and b/tests/data/binary_image.tif differ
diff --git a/tests/data/binary_tight_junctions.png b/tests/data/binary_tight_junctions.png
new file mode 100644
index 0000000..30f5b40
Binary files /dev/null and b/tests/data/binary_tight_junctions.png differ
diff --git a/tests/data/circles.png b/tests/data/circles.png
new file mode 100644
index 0000000..ff2f2b9
Binary files /dev/null and b/tests/data/circles.png differ
diff --git a/tests/data/cropped_refined_binary_image.tif b/tests/data/cropped_refined_binary_image.tif
new file mode 100644
index 0000000..e6b3dcd
Binary files /dev/null and b/tests/data/cropped_refined_binary_image.tif differ
diff --git a/tests/data/greyscale_image.jpg b/tests/data/greyscale_image.jpg
new file mode 100644
index 0000000..86aa0f9
Binary files /dev/null and b/tests/data/greyscale_image.jpg differ
diff --git a/tests/data/histological_section/images/image1.tif b/tests/data/histological_section/images/image1.tif
new file mode 100644
index 0000000..f9c610e
Binary files /dev/null and b/tests/data/histological_section/images/image1.tif differ
diff --git a/tests/data/image.tif b/tests/data/image.tif
new file mode 100644
index 0000000..f9c610e
Binary files /dev/null and b/tests/data/image.tif differ
diff --git a/tests/data/lena.tif b/tests/data/lena.tif
new file mode 100644
index 0000000..ffe5c83
Binary files /dev/null and b/tests/data/lena.tif differ
diff --git a/tests/data/live_cell_imaging/compds_df.csv b/tests/data/live_cell_imaging/compds_df.csv
new file mode 100644
index 0000000..bfe4be4
--- /dev/null
+++ b/tests/data/live_cell_imaging/compds_df.csv
@@ -0,0 +1,2 @@
+,Date Time,Elapsed,C55 10 µM (A1),C55 10 µM (A2),C55 10 µM (A3),C55 10 µM (A4),C55 10 µM (A5),,C57 10 µM (A6),C57 10 µM (A7),C57 10 µM (A8),C57 10 µM (A9),C57 10 µM (A10),,DMSO 0.05% (A11),DMSO 0.05% (B11),DMSO 0.05% (C11),DMSO 0.05% (D11),DMSO 0.05% (E11),DMSO 0.05% (F11),,UT 100% (A12),UT 100% (B12),UT 100% (C12),UT 100% (D12),UT 100% (E12),UT 100% (F12),,C55 1 µM (B1),C55 1 µM (B2),C55 1 µM (B3),C55 1 µM (B4),C55 1 µM (B5),,C57 1 µM (B6),C57 1 µM (B7),C57 1 µM (B8),C57 1 µM (B9),C57 1 µM (B10),,C55 0.1 µM (C1),C55 0.1 µM (C2),C55 0.1 µM (C3),C55 0.1 µM (C4),C55 0.1 µM (C5),,C57 0.1 µM (C6),C57 0.1 µM (C7),C57 0.1 µM (C8),C57 0.1 µM (C9),C57 0.1 µM (C10),,C55 0.01 µM (D1),C55 0.01 µM (D2),C55 0.01 µM (D3),C55 0.01 µM (D4),C55 0.01 µM (D5),,C57 0.01 µM (D6),C57 0.01 µM (D7),C57 0.01 µM (D8),C57 0.01 µM (D9),C57 0.01 µM (D10),,C56 10 µM (E1),C56 10 µM (E2),C56 10 µM (E3),C56 10 µM (E4),C56 10 µM (E5),,C58 10 µM (E6),C58 10 µM (E7),C58 10 µM (E8),C58 10 µM (E9),C58 10 µM (E10),,C56 1 µM (F1),C56 1 µM (F2),C56 1 µM (F3),C56 1 µM (F4),C56 1 µM (F5),,C58 1 µM (F6),C58 1 µM (F7),C58 1 µM (F8),C58 1 µM (F9),C58 1 µM (F10),,C56 0.1 µM (G1),C56 0.1 µM (G2),C56 0.1 µM (G3),C56 0.1 µM (G4),C56 0.1 µM (G5),,C58 0.1 µM (G6),C58 0.1 µM (G7),C58 0.1 µM (G8),C58 0.1 µM (G9),C58 0.1 µM (G10),,Pos 10 µM (G11),Pos 10 µM (G12),Pos 10 µM (H11),Pos 10 µM (H12),,C56 0.01 µM (H1),C56 0.01 µM (H2),C56 0.01 µM (H3),C56 0.01 µM (H4),C56 0.01 µM (H5),,C58 0.01 µM (H6),C58 0.01 µM (H7),C58 0.01 µM (H8),C58 0.01 µM (H9),C58 0.01 µM (H10),
+10,28/07/2022 0:00,6,151.28563299603485,71.285182542305,0.0,3.9356467900805776,0.0,,135.05099903840886,193.19357815742825,144.4399240220046,118.71369330290338,157.898592879765,,120.78314108292199,115.63899467965317,186.5862489453213,90.5586195915832,24.941266706241198,61.49172899427913,,170.9691413021223,294.3734480048936,177.33294396652533,135.4787101336627,87.0554620495042,154.39116834434654,,134.89694738196755,0.0,0.0,0.0,160.33390234642624,,145.43738870213218,168.85262462650337,116.15411315393295,133.1025667086672,7.880815573751472,,46.48783668254553,50.29368681399422,328.1215822125676,0.0,46.71601085215178,,85.21528817964324,51.711208395137845,101.4494382514266,104.37408827384263,51.85197518571813,,145.80294246142037,61.684799445484416,43.19079251461154,89.15640639891518,70.32009422401086,,106.20577214664672,55.42190897407866,0.0,71.6832886219149,53.76020100090027,,114.7257261361414,85.00057483438623,49.5592360841415,95.9414096945077,81.33082859357987,,56.996957391806035,67.6689716715412,172.99684293080946,59.76403658801623,18.42397105359698,,236.94592019240005,113.66746779833194,0.0,0.0,242.66091992109406,,108.21205082939242,169.85391640374988,137.7242923603949,117.21835408034207,192.8421010771981,,282.8288555820488,158.87555839601433,136.69211986846486,115.50869741912229,216.95360473947707,,272.3539587987481,163.24737900483996,145.4791788430857,122.79716193914965,187.06846318230293,,373.9714374064299,264.02540365482054,453.6328598429716,271.87178855138853,,255.42173741455264,240.72374893459886,271.30700579380715,197.2261068113333,77.4312365775291,,220.10365758530983,247.96338497414365,210.01679325816812,248.33430546732274,-97.71823850860753,
diff --git a/tests/data/live_cell_imaging/ctrl_df.csv b/tests/data/live_cell_imaging/ctrl_df.csv
new file mode 100644
index 0000000..9e17915
--- /dev/null
+++ b/tests/data/live_cell_imaging/ctrl_df.csv
@@ -0,0 +1,5 @@
+,DMSO 0.05% (A11),DMSO 0.05% (B11),DMSO 0.05% (C11),DMSO 0.05% (D11),DMSO 0.05% (E11),DMSO 0.05% (F11),Average,StDev,SEM,
+8,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+9,1.624458,1.587884,2.080587,1.17492,0.4584868,0.849259,1.2959324666666667,0.5872518894102825,45.31500710996019,
+10,2.745719,2.628779,4.241597,2.058636,0.5669807,1.397869,2.27326345,1.2607714880504772,55.460861258754555,
+11,4.02871,4.009587,5.759967,3.06436,1.229087,2.486529,3.4297066666666667,1.548610256358993,45.15284853395605,
diff --git a/tests/data/live_cell_imaging/dfs.pickle b/tests/data/live_cell_imaging/dfs.pickle
new file mode 100644
index 0000000..2e64dae
Binary files /dev/null and b/tests/data/live_cell_imaging/dfs.pickle differ
diff --git a/tests/data/live_cell_imaging/figures/C55_wound_closure.png b/tests/data/live_cell_imaging/figures/C55_wound_closure.png
new file mode 100644
index 0000000..1df86d7
Binary files /dev/null and b/tests/data/live_cell_imaging/figures/C55_wound_closure.png differ
diff --git a/tests/data/live_cell_imaging/figures/C56_wound_closure.png b/tests/data/live_cell_imaging/figures/C56_wound_closure.png
new file mode 100644
index 0000000..2d5bc71
Binary files /dev/null and b/tests/data/live_cell_imaging/figures/C56_wound_closure.png differ
diff --git a/tests/data/live_cell_imaging/figures/C57_wound_closure.png b/tests/data/live_cell_imaging/figures/C57_wound_closure.png
new file mode 100644
index 0000000..dd3e983
Binary files /dev/null and b/tests/data/live_cell_imaging/figures/C57_wound_closure.png differ
diff --git a/tests/data/live_cell_imaging/figures/C58_wound_closure.png b/tests/data/live_cell_imaging/figures/C58_wound_closure.png
new file mode 100644
index 0000000..3be8b03
Binary files /dev/null and b/tests/data/live_cell_imaging/figures/C58_wound_closure.png differ
diff --git a/tests/data/live_cell_imaging/fld_chg_df.csv b/tests/data/live_cell_imaging/fld_chg_df.csv
new file mode 100644
index 0000000..f51300e
--- /dev/null
+++ b/tests/data/live_cell_imaging/fld_chg_df.csv
@@ -0,0 +1,5 @@
+,C55 10 µM (A1),C55 10 µM (A2),C55 10 µM (A3),C55 10 µM (A4),C55 10 µM (A5),,C57 10 µM (A6),C57 10 µM (A7),C57 10 µM (A8),C57 10 µM (A9),C57 10 µM (A10),,DMSO 0.05% (A11),DMSO 0.05% (B11),DMSO 0.05% (C11),DMSO 0.05% (D11),DMSO 0.05% (E11),DMSO 0.05% (F11),,UT 100% (A12),UT 100% (B12),UT 100% (C12),UT 100% (D12),UT 100% (E12),UT 100% (F12),,C55 1 µM (B1),C55 1 µM (B2),C55 1 µM (B3),C55 1 µM (B4),C55 1 µM (B5),,C57 1 µM (B6),C57 1 µM (B7),C57 1 µM (B8),C57 1 µM (B9),C57 1 µM (B10),,C55 0.1 µM (C1),C55 0.1 µM (C2),C55 0.1 µM (C3),C55 0.1 µM (C4),C55 0.1 µM (C5),,C57 0.1 µM (C6),C57 0.1 µM (C7),C57 0.1 µM (C8),C57 0.1 µM (C9),C57 0.1 µM (C10),,C55 0.01 µM (D1),C55 0.01 µM (D2),C55 0.01 µM (D3),C55 0.01 µM (D4),C55 0.01 µM (D5),,C57 0.01 µM (D6),C57 0.01 µM (D7),C57 0.01 µM (D8),C57 0.01 µM (D9),C57 0.01 µM (D10),,C56 10 µM (E1),C56 10 µM (E2),C56 10 µM (E3),C56 10 µM (E4),C56 10 µM (E5),,C58 10 µM (E6),C58 10 µM (E7),C58 10 µM (E8),C58 10 µM (E9),C58 10 µM (E10),,C56 1 µM (F1),C56 1 µM (F2),C56 1 µM (F3),C56 1 µM (F4),C56 1 µM (F5),,C58 1 µM (F6),C58 1 µM (F7),C58 1 µM (F8),C58 1 µM (F9),C58 1 µM (F10),,C56 0.1 µM (G1),C56 0.1 µM (G2),C56 0.1 µM (G3),C56 0.1 µM (G4),C56 0.1 µM (G5),,C58 0.1 µM (G6),C58 0.1 µM (G7),C58 0.1 µM (G8),C58 0.1 µM (G9),C58 0.1 µM (G10),,Pos 10 µM (G11),Pos 10 µM (G12),Pos 10 µM (H11),Pos 10 µM (H12),,C56 0.01 µM (H1),C56 0.01 µM (H2),C56 0.01 µM (H3),C56 0.01 µM (H4),C56 0.01 µM (H5),,C58 0.01 µM (H6),C58 0.01 µM (H7),C58 0.01 µM (H8),C58 0.01 µM (H9),C58 0.01 µM (H10),
+8,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,
+9,226.97355577222206,59.49007528015734,0.0,-74.55052055953327,0.0,,93.33048064695963,147.15404151461183,145.92025808752277,111.54987140019179,181.29849050261723,,125.35051337808909,122.52829841390398,160.54748634792543,90.66213172527972,35.37891146282469,65.53265867197709,,170.64369146396362,293.576640593463,194.70304702606157,86.30974443267029,124.19242834001587,191.60967595687984,,177.18261244786058,0.0,0.0,0.0,143.31325495510646,,164.03084687489118,183.1226596324181,92.16467915740671,68.50992801219529,-12.463172592275512,,53.953112371544876,39.79245934986221,397.3754908113267,0.0,53.944207586537296,,73.60556391132933,49.20647613993466,68.28833467505277,103.63294651105019,26.28531260399526,,147.36331167874127,78.05568777838063,-24.030627213239043,90.37963243660793,42.80681395589184,,114.57927308660683,13.365789071210346,0.0,31.654311513249116,60.07373223717881,,137.09479820116138,9.178209749304324,56.56554788580289,36.414258623661816,55.967353134193665,,36.535036522222065,63.05082409901297,223.61983163011527,41.407358315533614,35.703457695609345,,259.14621991362,100.52676613241213,0.0,0.0,213.0843289313378,,78.60965183010823,153.44950845432427,109.36727309915892,122.33392100113034,211.38694109934843,,350.09995634031753,97.10899544302384,76.05450325163548,124.2476781326105,235.06672441316,,286.3960966690291,111.40032657051522,66.66919937751899,120.79333146320843,279.6448189404108,,397.38482771761716,275.5996235812082,593.4323892495015,249.92567771149803,,304.98255901915053,307.67413445978434,282.0229521219393,260.68202525162445,291.03939418242317,,200.43992004315862,280.721958402462,260.08068218781153,292.6218840518799,304.436542912447,
+10,151.28563299603485,71.285182542305,0.0,3.9356467900805776,0.0,,135.05099903840886,193.19357815742825,144.4399240220046,118.71369330290338,157.898592879765,,120.78314108292199,115.63899467965317,186.5862489453213,90.5586195915832,24.941266706241198,61.49172899427913,,170.9691413021223,294.3734480048936,177.33294396652533,135.4787101336627,87.0554620495042,154.39116834434654,,134.89694738196755,0.0,0.0,0.0,160.33390234642624,,145.43738870213218,168.85262462650337,116.15411315393295,133.1025667086672,7.880815573751472,,46.48783668254553,50.29368681399422,328.1215822125676,0.0,46.71601085215178,,85.21528817964324,51.711208395137845,101.4494382514266,104.37408827384263,51.85197518571813,,145.80294246142037,61.684799445484416,43.19079251461154,89.15640639891518,70.32009422401086,,106.20577214664672,55.42190897407866,0.0,71.6832886219149,53.76020100090027,,114.7257261361414,85.00057483438623,49.5592360841415,95.9414096945077,81.33082859357987,,56.996957391806035,67.6689716715412,172.99684293080946,59.76403658801623,18.42397105359698,,236.94592019240005,113.66746779833194,0.0,0.0,242.66091992109406,,108.21205082939242,169.85391640374988,137.7242923603949,117.21835408034207,192.8421010771981,,282.8288555820488,158.87555839601433,136.69211986846486,115.50869741912229,216.95360473947707,,272.3539587987481,163.24737900483996,145.4791788430857,122.79716193914965,187.06846318230293,,373.9714374064299,264.02540365482054,453.6328598429716,271.87178855138853,,255.42173741455264,240.72374893459886,271.30700579380715,197.2261068113333,77.4312365775291,,220.10365758530983,247.96338497414365,210.01679325816812,248.33430546732274,-97.71823850860753,
+11,109.05437005302687,60.658044614116655,0.0,7.89658202061984,0.0,,129.64353608471862,178.18287666972492,148.83214502309235,138.08466613276937,139.40819039917892,,117.4651476511111,116.90757810191737,167.94342956443307,89.34758268928734,35.83650496835492,72.49975702489621,,163.74368264730123,279.90650318005817,173.52358607927596,117.16579260422661,88.28851252585255,135.0533281757818,,118.33090682196341,0.0,0.0,0.0,159.52303015223848,,121.84791313542851,157.9735973533208,124.73541954997123,118.12858631253206,11.214623796787286,,37.77159757102648,46.77545795947564,279.8762673581415,0.0,38.542713079447026,,78.71734414604941,43.10260741443389,77.10519461333914,83.03853002006002,54.969569798000215,,137.11779044272006,52.61377066260282,47.15476153451413,59.398082634860906,79.4918710249273,,103.07353787301538,59.03522361484753,0.0,66.75471760461535,56.1489709518404,,116.63026575644952,102.23734391279334,43.831970081017616,68.21224750027213,78.68506733326076,,72.14654897600572,72.07905049217037,171.53017945169267,48.668710249273026,25.506991851586918,,276.1188906339901,103.81188089943552,0.0,0.0,234.24288957656242,,84.27499144727635,162.32420265289934,135.0096509711229,111.88260026124684,202.51752336448598,,318.91065513863185,168.53219711695462,124.36868264730123,157.1069634720948,208.77715489760055,,279.80559075994836,166.0912303481736,168.94083264652372,139.95045251683334,222.7293684979862,,376.9316520752017,240.12237198127733,393.18114668698587,239.4354910818418,,270.2750672555087,301.35813364019464,293.6819669709363,243.45641804158177,140.9126630848897,,260.7117712690687,280.5801467958387,305.522921299392,295.5751317896963,73.79948916914176,
diff --git a/tests/data/live_cell_imaging/fld_chg_stats_df.csv b/tests/data/live_cell_imaging/fld_chg_stats_df.csv
new file mode 100644
index 0000000..fda3f82
--- /dev/null
+++ b/tests/data/live_cell_imaging/fld_chg_stats_df.csv
@@ -0,0 +1,5 @@
+,C55 10 µM (A1),C55 10 µM (A2),C55 10 µM (A3),C55 10 µM (A4),C55 10 µM (A5),Average,StDev,SEM,,C57 10 µM (A6),C57 10 µM (A7),C57 10 µM (A8),C57 10 µM (A9),C57 10 µM (A10),Average,StDev,SEM,,DMSO 0.05% (A11),DMSO 0.05% (B11),DMSO 0.05% (C11),DMSO 0.05% (D11),DMSO 0.05% (E11),DMSO 0.05% (F11),Average,StDev,SEM,,UT 100% (A12),UT 100% (B12),UT 100% (C12),UT 100% (D12),UT 100% (E12),UT 100% (F12),Average,StDev,SEM,,C55 1 µM (B1),C55 1 µM (B2),C55 1 µM (B3),C55 1 µM (B4),C55 1 µM (B5),Average,StDev,SEM,,C57 1 µM (B6),C57 1 µM (B7),C57 1 µM (B8),C57 1 µM (B9),C57 1 µM (B10),Average,StDev,SEM,,C55 0.1 µM (C1),C55 0.1 µM (C2),C55 0.1 µM (C3),C55 0.1 µM (C4),C55 0.1 µM (C5),Average,StDev,SEM,,C57 0.1 µM (C6),C57 0.1 µM (C7),C57 0.1 µM (C8),C57 0.1 µM (C9),C57 0.1 µM (C10),Average,StDev,SEM,,C55 0.01 µM (D1),C55 0.01 µM (D2),C55 0.01 µM (D3),C55 0.01 µM (D4),C55 0.01 µM (D5),Average,StDev,SEM,,C57 0.01 µM (D6),C57 0.01 µM (D7),C57 0.01 µM (D8),C57 0.01 µM (D9),C57 0.01 µM (D10),Average,StDev,SEM,,C56 10 µM (E1),C56 10 µM (E2),C56 10 µM (E3),C56 10 µM (E4),C56 10 µM (E5),Average,StDev,SEM,,C58 10 µM (E6),C58 10 µM (E7),C58 10 µM (E8),C58 10 µM (E9),C58 10 µM (E10),Average,StDev,SEM,,C56 1 µM (F1),C56 1 µM (F2),C56 1 µM (F3),C56 1 µM (F4),C56 1 µM (F5),Average,StDev,SEM,,C58 1 µM (F6),C58 1 µM (F7),C58 1 µM (F8),C58 1 µM (F9),C58 1 µM (F10),Average,StDev,SEM,,C56 0.1 µM (G1),C56 0.1 µM (G2),C56 0.1 µM (G3),C56 0.1 µM (G4),C56 0.1 µM (G5),Average,StDev,SEM,,C58 0.1 µM (G6),C58 0.1 µM (G7),C58 0.1 µM (G8),C58 0.1 µM (G9),C58 0.1 µM (G10),Average,StDev,SEM,,Pos 10 µM (G11),Pos 10 µM (G12),Pos 10 µM (H11),Pos 10 µM (H12),Average,StDev,SEM,,C56 0.01 µM (H1),C56 0.01 µM (H2),C56 0.01 µM (H3),C56 0.01 µM (H4),C56 0.01 µM (H5),Average,StDev,SEM,,C58 0.01 µM (H6),C58 0.01 µM (H7),C58 0.01 µM (H8),C58 0.01 µM (H9),C58 0.01 µM (H10),Average,StDev,SEM,
+8,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+9,226.97355577222206,59.49007528015734,0.0,-74.55052055953327,0.0,42.38262209856923,113.61383158827046,268.06701889288223,,93.33048064695963,147.15404151461183,145.92025808752277,111.54987140019179,181.29849050261723,135.85062843038065,34.25333018658931,25.21396520748751,,125.35051337808909,122.52829841390398,160.54748634792543,90.66213172527972,35.37891146282469,65.53265867197709,100.0,45.31500710996019,45.31500710996019,,170.64369146396362,293.576640593463,194.70304702606157,86.30974443267029,124.19242834001587,191.60967595687984,176.83920463550902,70.95148094921093,40.12203125175332,,177.18261244786058,0.0,0.0,0.0,143.31325495510646,64.09917348059341,88.58448932403468,138.19911320830747,,164.03084687489118,183.1226596324181,92.16467915740671,68.50992801219529,-12.463172592275512,99.07298821692716,78.59072976133423,79.32609198104976,,53.953112371544876,39.79245934986221,397.3754908113267,0.0,53.944207586537296,109.01305402385421,162.70556739654793,149.25328792361395,,73.60556391132933,49.20647613993466,68.28833467505277,103.63294651105019,26.28531260399526,64.20372676827245,28.82041634017362,44.889008459265646,,147.36331167874127,78.05568777838063,-24.030627213239043,90.37963243660793,42.80681395589184,66.91496372727653,63.243470997132526,94.51319626338316,,114.57927308660683,13.365789071210346,0.0,31.654311513249116,60.07373223717881,43.93462118164902,45.46055484966711,103.473191817699,,137.09479820116138,9.178209749304324,56.56554788580289,36.414258623661816,55.967353134193665,59.04403351882482,47.71330478162871,80.80969733616932,,36.535036522222065,63.05082409901297,223.61983163011527,41.407358315533614,35.703457695609345,80.06330165249865,81.01649410478718,101.19054851925256,,259.14621991362,100.52676613241213,0.0,0.0,213.0843289313378,114.55146299547398,119.43317887909154,104.26159191333109,,78.60965183010823,153.44950845432427,109.36727309915892,122.33392100113034,211.38694109934843,135.02945909681404,50.429858233565135,37.34730078227426,,350.09995634031753,97.10899544302384,76.05450325163548,124.2476781326105,235.06672441316,176.51557151614946,114.77101049438768,65.02033192232406,,286.3960966690291,111.40032657051522,66.66919937751899,120.79333146320843,279.6448189404108,172.9807546041365,102.54034018622364,59.27846737683938,,397.38482771761716,275.5996235812082,593.4323892495015,249.92567771149803,379.0856295649562,156.70677568583363,41.33809447371362,,304.98255901915053,307.67413445978434,282.0229521219393,260.68202525162445,291.03939418242317,289.28021300698435,19.095280264701582,6.600963151337471,,200.43992004315862,280.721958402462,260.08068218781153,292.6218840518799,304.436542912447,267.6601975195518,40.99454149342762,15.31589002523735,
+10,151.28563299603485,71.285182542305,0.0,3.9356467900805776,0.0,45.301292465684085,66.56458108756063,146.93748779460006,,135.05099903840886,193.19357815742825,144.4399240220046,118.71369330290338,157.898592879765,149.859357480102,28.112248768577942,18.759088015114855,,120.78314108292199,115.63899467965317,186.5862489453213,90.5586195915832,24.941266706241198,61.49172899427913,100.0,55.460861258754555,55.460861258754555,,170.9691413021223,294.3734480048936,177.33294396652533,135.4787101336627,87.0554620495042,154.39116834434654,169.93347896684244,69.04866512240477,40.632761444187,,134.89694738196755,0.0,0.0,0.0,160.33390234642624,59.046169945678756,81.35093073889318,137.7751187142779,,145.43738870213218,168.85262462650337,116.15411315393295,133.1025667086672,7.880815573751472,114.28550175299743,62.505083477668805,54.69204975164704,,46.48783668254553,50.29368681399422,328.1215822125676,0.0,46.71601085215178,94.32382331225183,132.33651617673388,140.30020362792538,,85.21528817964324,51.711208395137845,101.4494382514266,104.37408827384263,51.85197518571813,78.9203996571537,25.826890822294793,32.72524079261138,,145.80294246142037,61.684799445484416,43.19079251461154,89.15640639891518,70.32009422401086,82.03100700888848,39.2979228785023,47.90618122516059,,106.20577214664672,55.42190897407866,0.0,71.6832886219149,53.76020100090027,57.41423414870811,38.399009415911536,66.88064377285708,,114.7257261361414,85.00057483438623,49.5592360841415,95.9414096945077,81.33082859357987,85.31155506855134,23.83463065426015,27.93833805409835,,56.996957391806035,67.6689716715412,172.99684293080946,59.76403658801623,18.42397105359698,75.17015592715398,57.90956659125646,77.03797587885217,,236.94592019240005,113.66746779833194,0.0,0.0,242.66091992109406,118.65486158236521,119.95113953482104,101.09247774188839,,108.21205082939242,169.85391640374988,137.7242923603949,117.21835408034207,192.8421010771981,145.17014295021548,35.653008389227644,24.559463581608824,,282.8288555820488,158.87555839601433,136.69211986846486,115.50869741912229,216.95360473947707,182.17176720102546,67.8172216380619,37.22707567700433,,272.3539587987481,163.24737900483996,145.4791788430857,122.79716193914965,187.06846318230293,178.18922835362528,57.678688641375324,32.36934643821967,,373.9714374064299,264.02540365482054,453.6328598429716,271.87178855138853,340.87537236390267,90.32720663131558,26.498601528445555,,255.42173741455264,240.72374893459886,271.30700579380715,197.2261068113333,77.4312365775291,208.4219671063642,78.24773220555066,37.54293911141258,,220.10365758530983,247.96338497414365,210.01679325816812,248.33430546732274,-97.71823850860753,165.73998055526735,148.24691350713803,89.44547538287172,
+11,109.05437005302687,60.658044614116655,0.0,7.89658202061984,0.0,35.52179933755267,48.284621958736196,135.92954990793785,,129.64353608471862,178.18287666972492,148.83214502309235,138.08466613276937,139.40819039917892,146.83028286189685,18.801264078991206,12.804759149497096,,117.4651476511111,116.90757810191737,167.94342956443307,89.34758268928734,35.83650496835492,72.49975702489621,100.0,45.152848533956046,45.152848533956046,,163.74368264730123,279.90650318005817,173.52358607927596,117.16579260422661,88.28851252585255,135.0533281757818,159.61356753541605,66.59312165511189,41.721466842306995,,118.33090682196341,0.0,0.0,0.0,159.52303015223848,55.57078739484038,77.47457421607334,139.41600946843283,,121.84791313542851,157.9735973533208,124.73541954997123,118.12858631253206,11.214623796787286,106.78002802960798,55.74889023020297,52.20909870406187,,37.77159757102648,46.77545795947564,279.8762673581415,0.0,38.542713079447026,80.59320719361813,112.86560324504252,140.04356840383926,,78.71734414604941,43.10260741443389,77.10519461333914,83.03853002006002,54.969569798000215,67.38664919837653,17.404846253526745,25.828330181976256,,137.11779044272006,52.61377066260282,47.15476153451413,59.398082634860906,79.4918710249273,75.15525525992504,36.73757160056493,48.88223913751307,,103.07353787301538,59.03522361484753,0.0,66.75471760461535,56.1489709518404,57.00249000886373,36.98578024824033,64.88449933062424,,116.63026575644952,102.23734391279334,43.831970081017616,68.21224750027213,78.68506733326076,81.91937891675867,28.577361239654284,34.884738651025174,,72.14654897600572,72.07905049217037,171.53017945169267,48.668710249273026,25.506991851586918,77.98629620414575,55.75180383667143,71.48923150642929,,276.1188906339901,103.81188089943552,0.0,0.0,234.24288957656242,122.8347322219976,128.8860179555489,104.92636376054851,,84.27499144727635,162.32420265289934,135.0096509711229,111.88260026124684,202.51752336448598,139.2017937394063,45.619056914968354,32.771888701642624,,318.91065513863185,168.53219711695462,124.36868264730123,157.1069634720948,208.77715489760055,195.5391306545166,75.2785111143658,38.497926661732855,,279.80559075994836,166.0912303481736,168.94083264652372,139.95045251683334,222.7293684979862,195.50349495389304,55.91262918527046,28.599299055219817,,376.9316520752017,240.12237198127733,393.18114668698587,239.4354910818418,312.4176654563267,84.13838126369888,26.93137762898388,,270.2750672555087,301.35813364019464,293.6819669709363,243.45641804158177,140.9126630848897,249.9368497986222,64.99941553969374,26.00633543715732,,260.7117712690687,280.5801467958387,305.522921299392,295.5751317896963,73.79948916914176,243.2378920646275,96.21299853378675,39.55510291473143,
diff --git a/tests/data/live_cell_imaging/info_df.csv b/tests/data/live_cell_imaging/info_df.csv
new file mode 100644
index 0000000..87dd69e
--- /dev/null
+++ b/tests/data/live_cell_imaging/info_df.csv
@@ -0,0 +1,6 @@
+Vessel Name: 220727_2%FCS_X_C55_C56_C57_C58
+Metric: Relative Wound Density (%)
+Cell Type: X
+Passage: 24
+Notes: C55_C56_C57_C58
+Analysis: X_Wounding_CS_V2
diff --git a/tests/data/live_cell_imaging/metrics_df.csv b/tests/data/live_cell_imaging/metrics_df.csv
new file mode 100644
index 0000000..de90ae6
--- /dev/null
+++ b/tests/data/live_cell_imaging/metrics_df.csv
@@ -0,0 +1,5 @@
+,CA 10 µM (A1),CA 10 µM (A2),CA 10 µM (A3),CA 10 µM (A4),CA 10 µM (A5),,CC 10 µM (A6),CC 10 µM (A7),CC 10 µM (A8),CC 10 µM (A9),CC 10 µM (A10),,DMSO 0.05% (A11),DMSO 0.05% (B11),DMSO 0.05% (C11),DMSO 0.05% (D11),DMSO 0.05% (E11),DMSO 0.05% (F11),,UT 100% (A12),UT 100% (B12),UT 100% (C12),UT 100% (D12),UT 100% (E12),UT 100% (F12),,CA 1 µM (B1),CA 1 µM (B2),CA 1 µM (B3),CA 1 µM (B4),CA 1 µM (B5),,CC 1 µM (B6),CC 1 µM (B7),CC 1 µM (B8),CC 1 µM (B9),CC 1 µM (B10),,CA 0.1 µM (C1),CA 0.1 µM (C2),CA 0.1 µM (C3),CA 0.1 µM (C4),CA 0.1 µM (C5),,CC 0.1 µM (C6),CC 0.1 µM (C7),CC 0.1 µM (C8),CC 0.1 µM (C9),CC 0.1 µM (C10),,CA 0.01 µM (D1),CA 0.01 µM (D2),CA 0.01 µM (D3),CA 0.01 µM (D4),CA 0.01 µM (D5),,CC 0.01 µM (D6),CC 0.01 µM (D7),CC 0.01 µM (D8),CC 0.01 µM (D9),CC 0.01 µM (D10),,CB 10 µM (E1),CB 10 µM (E2),CB 10 µM (E3),CB 10 µM (E4),CB 10 µM (E5),,CD 10 µM (E6),CD 10 µM (E7),CD 10 µM (E8),CD 10 µM (E9),CD 10 µM (E10),,CB 1 µM (F1),CB 1 µM (F2),CB 1 µM (F3),CB 1 µM (F4),CB 1 µM (F5),,CD 1 µM (F6),CD 1 µM (F7),CD 1 µM (F8),CD 1 µM (F9),CD 1 µM (F10),,CB 0.1 µM (G1),CB 0.1 µM (G2),CB 0.1 µM (G3),CB 0.1 µM (G4),CB 0.1 µM (G5),,CD 0.1 µM (G6),CD 0.1 µM (G7),CD 0.1 µM (G8),CD 0.1 µM (G9),CD 0.1 µM (G10),,Pos 10 µM (G11),Pos 10 µM (G12),Pos 10 µM (H11),Pos 10 µM (H12),,CB 0.01 µM (H1),CB 0.01 µM (H2),CB 0.01 µM (H3),CB 0.01 µM (H4),CB 0.01 µM (H5),,CD 0.01 µM (H6),CD 0.01 µM (H7),CD 0.01 µM (H8),CD 0.01 µM (H9),CD 0.01 µM (H10),
+8,0,0,0,0,0,,0,0,0,0,0,,0,0,0,0,0,0,,0,0,0,0,0,0,,0,0,0,0,0,,0,0,0,0,0,,0,0,0,0,0,,0,0,0,0,0,,0,0,0,0,0,,0,0,0,0,0,,0,0,0,0,0,,0,0,0,0,0,,0,0,0,0,0,,0,0,0,0,0,,0,0,0,0,0,,0,0,0,0,0,,0,0,0,0,,0,0,0,0,0,,0,0,0,0,0,
+9,2.941424,0.7709512,,-0.9661244,,,1.2095,1.907017,1.891028,1.445611,2.349506,,1.624458,1.587884,2.080587,1.17492,0.4584868,0.849259,,2.211427,3.804555,2.52322,1.118516,1.60945,2.483132,,2.296167,0,0,,1.857243,,2.125729,2.373146,1.194392,0.8878424,-0.1615143,,0.6991959,0.5156834,5.149718,,0.6990805,,0.9538784,0.6376827,0.8849707,1.343013,0.3406399,,1.909729,1.011549,-0.3114207,1.171259,0.5547474,,1.48487,0.1732116,0,0.4102185,0.778515,,1.776656,0.1189434,0.7330513,0.4719042,0.7252991,,0.4734694,0.8170961,2.897962,0.5366114,0.4626927,,3.35836,1.302759,,,2.761429,,1.018728,1.988602,1.417326,1.585365,2.739432,,4.537059,1.258467,0.985615,1.610166,3.046306,,3.7115,1.443673,0.8639878,1.5654,3.624008,,5.149839,3.571585,7.690483,3.238868,,3.952368,3.987249,3.654827,3.378263,3.771674,,2.597566,3.637967,3.37047,3.792182,3.945292,
+10,3.439121,1.6205,,0.08946762,,,3.070065,4.391799,3.2835,2.698675,3.589451,,2.745719,2.628779,4.241597,2.058636,0.5669807,1.397869,,3.886579,6.691884,4.031245,3.079788,1.979,3.509718,,3.066563,0,0,,3.644812,,3.306175,3.838465,2.640489,3.025772,0.1791517,,1.056791,1.143308,7.459068,,1.061978,,1.937168,1.175532,2.306213,2.372698,1.178732,,3.314485,1.402258,0.9818405,2.02676,1.598561,,2.414337,1.259886,0,1.62955,1.222111,,2.608018,1.932287,1.126612,2.181001,1.848864,,1.295691,1.538294,3.932674,1.358594,0.4188254,,5.386405,2.583961,,,5.516322,,2.459945,3.861227,3.130836,2.664682,4.383809,,6.429445,3.61166,3.107372,2.625817,4.931927,,6.191323,3.711043,3.307125,2.791503,4.252559,,8.501356,6.001993,10.31227,6.180362,,5.806409,5.472285,6.167523,4.483469,1.760216,,5.003536,5.636861,4.774235,5.645293,-2.221393,
+11,3.740245,2.080393,,0.2708296,,,4.446393,6.11115,5.104506,4.735899,4.781292,,4.02871,4.009587,5.759967,3.06436,1.229087,2.486529,,5.615928,9.599972,5.95135,4.018443,3.028037,4.631933,,4.058403,0,0,,5.471172,,4.179026,5.418031,4.278059,4.051464,0.3846287,,1.295455,1.604261,9.598935,,1.321902,,2.699774,1.478293,2.644482,2.847978,1.885295,,4.702738,1.804498,1.61727,2.03718,2.726338,,3.53512,2.024735,0,2.289491,1.925745,,4.000076,3.506441,1.503308,2.33948,2.698667,,2.474415,2.4721,5.882982,1.669194,0.874815,,9.470068,3.560443,,,8.033844,,2.890385,5.567244,4.630435,3.837245,6.945757,,10.9377,5.78016,4.265481,5.388308,7.160444,,9.596511,5.696442,5.794175,4.79989,7.638964,,12.92765,8.235493,13.48496,8.211935,,9.269642,10.3357,10.07243,8.349841,4.832891,,8.941649,9.623076,10.47854,10.13736,2.531106,
diff --git a/tests/data/live_cell_imaging/notes_compounds_df.csv b/tests/data/live_cell_imaging/notes_compounds_df.csv
new file mode 100644
index 0000000..cfb2226
--- /dev/null
+++ b/tests/data/live_cell_imaging/notes_compounds_df.csv
@@ -0,0 +1,5 @@
+,C55 10 µM (A1),C55 10 µM (A2),C55 10 µM (A3),C55 10 µM (A4),C55 10 µM (A5),,C57 10 µM (A6),C57 10 µM (A7),C57 10 µM (A8),C57 10 µM (A9),C57 10 µM (A10),,DMSO 0.05% (A11),DMSO 0.05% (B11),DMSO 0.05% (C11),DMSO 0.05% (D11),DMSO 0.05% (E11),DMSO 0.05% (F11),,UT 100% (A12),UT 100% (B12),UT 100% (C12),UT 100% (D12),UT 100% (E12),UT 100% (F12),,C55 1 µM (B1),C55 1 µM (B2),C55 1 µM (B3),C55 1 µM (B4),C55 1 µM (B5),,C57 1 µM (B6),C57 1 µM (B7),C57 1 µM (B8),C57 1 µM (B9),C57 1 µM (B10),,C55 0.1 µM (C1),C55 0.1 µM (C2),C55 0.1 µM (C3),C55 0.1 µM (C4),C55 0.1 µM (C5),,C57 0.1 µM (C6),C57 0.1 µM (C7),C57 0.1 µM (C8),C57 0.1 µM (C9),C57 0.1 µM (C10),,C55 0.01 µM (D1),C55 0.01 µM (D2),C55 0.01 µM (D3),C55 0.01 µM (D4),C55 0.01 µM (D5),,C57 0.01 µM (D6),C57 0.01 µM (D7),C57 0.01 µM (D8),C57 0.01 µM (D9),C57 0.01 µM (D10),,C56 10 µM (E1),C56 10 µM (E2),C56 10 µM (E3),C56 10 µM (E4),C56 10 µM (E5),,C58 10 µM (E6),C58 10 µM (E7),C58 10 µM (E8),C58 10 µM (E9),C58 10 µM (E10),,C56 1 µM (F1),C56 1 µM (F2),C56 1 µM (F3),C56 1 µM (F4),C56 1 µM (F5),,C58 1 µM (F6),C58 1 µM (F7),C58 1 µM (F8),C58 1 µM (F9),C58 1 µM (F10),,C56 0.1 µM (G1),C56 0.1 µM (G2),C56 0.1 µM (G3),C56 0.1 µM (G4),C56 0.1 µM (G5),,C58 0.1 µM (G6),C58 0.1 µM (G7),C58 0.1 µM (G8),C58 0.1 µM (G9),C58 0.1 µM (G10),,Pos 10 µM (G11),Pos 10 µM (G12),Pos 10 µM (H11),Pos 10 µM (H12),,C56 0.01 µM (H1),C56 0.01 µM (H2),C56 0.01 µM (H3),C56 0.01 µM (H4),C56 0.01 µM (H5),,C58 0.01 µM (H6),C58 0.01 µM (H7),C58 0.01 µM (H8),C58 0.01 µM (H9),C58 0.01 µM (H10),
+8,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0,0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,
+9,2.941424,0.7709512,,-0.9661244,,,1.2095,1.907017,1.891028,1.445611,2.349506,,1.624458,1.587884,2.080587,1.17492,0.4584868,0.849259,,2.211427,3.804555,2.52322,1.118516,1.60945,2.483132,,2.296167,0,0,,1.857243,,2.125729,2.373146,1.194392,0.8878424,-0.1615143,,0.6991959,0.5156834,5.149718,,0.6990805,,0.9538784,0.6376827,0.8849707,1.343013,0.3406399,,1.909729,1.011549,-0.3114207,1.171259,0.5547474,,1.48487,0.1732116,0,0.4102185,0.778515,,1.776656,0.1189434,0.7330513,0.4719042,0.7252991,,0.4734694,0.8170961,2.897962,0.5366114,0.4626927,,3.35836,1.302759,,,2.761429,,1.018728,1.988602,1.417326,1.585365,2.739432,,4.537059,1.258467,0.985615,1.610166,3.046306,,3.7115,1.443673,0.8639878,1.5654,3.624008,,5.149839,3.571585,7.690483,3.238868,,3.952368,3.987249,3.654827,3.378263,3.771674,,2.597566,3.637967,3.37047,3.792182,3.945292,
+10,3.439121,1.6205,,0.08946762,,,3.070065,4.391799,3.2835,2.698675,3.589451,,2.745719,2.628779,4.241597,2.058636,0.5669807,1.397869,,3.886579,6.691884,4.031245,3.079788,1.979,3.509718,,3.066563,0,0,,3.644812,,3.306175,3.838465,2.640489,3.025772,0.1791517,,1.056791,1.143308,7.459068,,1.061978,,1.937168,1.175532,2.306213,2.372698,1.178732,,3.314485,1.402258,0.9818405,2.02676,1.598561,,2.414337,1.259886,0,1.62955,1.222111,,2.608018,1.932287,1.126612,2.181001,1.848864,,1.295691,1.538294,3.932674,1.358594,0.4188254,,5.386405,2.583961,,,5.516322,,2.459945,3.861227,3.130836,2.664682,4.383809,,6.429445,3.61166,3.107372,2.625817,4.931927,,6.191323,3.711043,3.307125,2.791503,4.252559,,8.501356,6.001993,10.31227,6.180362,,5.806409,5.472285,6.167523,4.483469,1.760216,,5.003536,5.636861,4.774235,5.645293,-2.221393,
+11,3.740245,2.080393,,0.2708296,,,4.446393,6.11115,5.104506,4.735899,4.781292,,4.02871,4.009587,5.759967,3.06436,1.229087,2.486529,,5.615928,9.599972,5.95135,4.018443,3.028037,4.631933,,4.058403,0,0,,5.471172,,4.179026,5.418031,4.278059,4.051464,0.3846287,,1.295455,1.604261,9.598935,,1.321902,,2.699774,1.478293,2.644482,2.847978,1.885295,,4.702738,1.804498,1.61727,2.03718,2.726338,,3.53512,2.024735,0,2.289491,1.925745,,4.000076,3.506441,1.503308,2.33948,2.698667,,2.474415,2.4721,5.882982,1.669194,0.874815,,9.470068,3.560443,,,8.033844,,2.890385,5.567244,4.630435,3.837245,6.945757,,10.9377,5.78016,4.265481,5.388308,7.160444,,9.596511,5.696442,5.794175,4.79989,7.638964,,12.92765,8.235493,13.48496,8.211935,,9.269642,10.3357,10.07243,8.349841,4.832891,,8.941649,9.623076,10.47854,10.13736,2.531106,
diff --git a/tests/data/live_cell_imaging/stats_df.csv b/tests/data/live_cell_imaging/stats_df.csv
new file mode 100644
index 0000000..ae7c762
--- /dev/null
+++ b/tests/data/live_cell_imaging/stats_df.csv
@@ -0,0 +1,5 @@
+,C55 10 µM (A1),C55 10 µM (A2),C55 10 µM (A3),C55 10 µM (A4),C55 10 µM (A5),Average,StDev,SEM,,C57 10 µM (A6),C57 10 µM (A7),C57 10 µM (A8),C57 10 µM (A9),C57 10 µM (A10),Average,StDev,SEM,,DMSO 0.05% (A11),DMSO 0.05% (B11),DMSO 0.05% (C11),DMSO 0.05% (D11),DMSO 0.05% (E11),DMSO 0.05% (F11),Average,StDev,SEM,,UT 100% (A12),UT 100% (B12),UT 100% (C12),UT 100% (D12),UT 100% (E12),UT 100% (F12),Average,StDev,SEM,,C55 1 µM (B1),C55 1 µM (B2),C55 1 µM (B3),C55 1 µM (B4),C55 1 µM (B5),Average,StDev,SEM,,C57 1 µM (B6),C57 1 µM (B7),C57 1 µM (B8),C57 1 µM (B9),C57 1 µM (B10),Average,StDev,SEM,,C55 0.1 µM (C1),C55 0.1 µM (C2),C55 0.1 µM (C3),C55 0.1 µM (C4),C55 0.1 µM (C5),Average,StDev,SEM,,C57 0.1 µM (C6),C57 0.1 µM (C7),C57 0.1 µM (C8),C57 0.1 µM (C9),C57 0.1 µM (C10),Average,StDev,SEM,,C55 0.01 µM (D1),C55 0.01 µM (D2),C55 0.01 µM (D3),C55 0.01 µM (D4),C55 0.01 µM (D5),Average,StDev,SEM,,C57 0.01 µM (D6),C57 0.01 µM (D7),C57 0.01 µM (D8),C57 0.01 µM (D9),C57 0.01 µM (D10),Average,StDev,SEM,,C56 10 µM (E1),C56 10 µM (E2),C56 10 µM (E3),C56 10 µM (E4),C56 10 µM (E5),Average,StDev,SEM,,C58 10 µM (E6),C58 10 µM (E7),C58 10 µM (E8),C58 10 µM (E9),C58 10 µM (E10),Average,StDev,SEM,,C56 1 µM (F1),C56 1 µM (F2),C56 1 µM (F3),C56 1 µM (F4),C56 1 µM (F5),Average,StDev,SEM,,C58 1 µM (F6),C58 1 µM (F7),C58 1 µM (F8),C58 1 µM (F9),C58 1 µM (F10),Average,StDev,SEM,,C56 0.1 µM (G1),C56 0.1 µM (G2),C56 0.1 µM (G3),C56 0.1 µM (G4),C56 0.1 µM (G5),Average,StDev,SEM,,C58 0.1 µM (G6),C58 0.1 µM (G7),C58 0.1 µM (G8),C58 0.1 µM (G9),C58 0.1 µM (G10),Average,StDev,SEM,,Pos 10 µM (G11),Pos 10 µM (G12),Pos 10 µM (H11),Pos 10 µM (H12),Average,StDev,SEM,,C56 0.01 µM (H1),C56 0.01 µM (H2),C56 0.01 µM (H3),C56 0.01 µM (H4),C56 0.01 µM (H5),Average,StDev,SEM,,C58 0.01 µM (H6),C58 0.01 µM (H7),C58 0.01 µM (H8),C58 0.01 µM (H9),C58 0.01 µM (H10),Average,StDev,SEM,
+8,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0,0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
+9,2.941424,0.7709512,,-0.9661244,,0.9154169333333333,1.9577758772817417,213.86712502169232,,1.2095,1.907017,1.891028,1.445611,2.349506,1.7605324,0.44390002680254476,25.213965207487504,,1.624458,1.587884,2.080587,1.17492,0.4584868,0.849259,1.2959324666666667,0.5872518894102825,45.31500710996019,,2.211427,3.804555,2.52322,1.118516,1.60945,2.483132,2.291716666666667,0.9194832772016394,40.12203125175331,,2.296167,0,0,,1.857243,1.0383525,1.2123023269675763,116.75248308908354,,2.125729,2.373146,1.194392,0.8878424,-0.1615143,1.2839190200000001,1.0184827827673928,79.32609198104976,,0.6991959,0.5156834,5.149718,,0.6990805,1.76591945,2.257522778405821,127.838377815354,,0.9538784,0.6376827,0.8849707,1.343013,0.3406399,0.8320369400000001,0.373493132380815,44.88900845926564,,1.909729,1.011549,-0.3114207,1.171259,0.5547474,0.86717274,0.8195926736987575,94.51319626338318,,1.48487,0.1732116,0,0.4102185,0.778515,0.5693630199999999,0.5891380898236439,103.473191817699,,1.776656,0.1189434,0.7330513,0.4719042,0.7252991,0.7651708,0.6183322075847457,80.80969733616935,,0.4734694,0.8170961,2.897962,0.5366114,0.4626927,1.03756632,1.0499190504590235,101.19054851925257,,3.35836,1.302759,,,2.761429,2.4741826666666666,1.05747657648306,42.740440741497125,,1.018728,1.988602,1.417326,1.585365,2.739432,1.7498906,0.6535369057427437,37.34730078227425,,4.537059,1.258467,0.985615,1.610166,3.046306,2.2875226,1.4873547873181772,65.02033192232406,,3.7115,1.443673,0.8639878,1.5654,3.624008,2.24171376,1.3288535599037195,59.27846737683938,,5.149839,3.571585,7.690483,3.238868,4.91269375,2.0308139835792245,41.338094473713625,,3.952368,3.987249,3.654827,3.378263,3.771674,3.7488761999999998,0.24746193655126025,6.600963151337466,,2.597566,3.637967,3.37047,3.792182,3.945292,3.4686954,0.5312615727744666,15.315890025237344,
+10,3.439121,1.6205,,0.08946762,,1.7163628733333334,1.6768830339052119,97.69979646836289,,3.070065,4.391799,3.2835,2.698675,3.589451,3.406698,0.6390654762291574,18.759088015114855,,2.745719,2.628779,4.241597,2.058636,0.5669807,1.397869,2.27326345,1.2607714880504772,55.460861258754555,,3.886579,6.691884,4.031245,3.079788,1.979,3.509718,3.8630356666666668,1.5696580669405253,40.632761444187,,3.066563,0,0,,3.644812,1.67784375,1.95173636801155,116.32408369441731,,3.306175,3.838465,2.640489,3.025772,0.1791517,2.5980105399999998,1.420905217089834,54.69204975164704,,1.056791,1.143308,7.459068,,1.061978,2.68028625,3.186100834034016,118.87166283205816,,1.937168,1.175532,2.306213,2.372698,1.178732,1.7940686000000001,0.5871132693346319,32.72524079261138,,3.314485,1.402258,0.9818405,2.02676,1.598561,1.8647809,0.8933453174061808,47.9061812251606,,2.414337,1.259886,0,1.62955,1.222111,1.3051768000000001,0.8729106462139754,66.88064377285708,,2.608018,1.932287,1.126612,2.181001,1.848864,1.9393564,0.541823947105792,27.938338054098356,,1.295691,1.538294,3.932674,1.358594,0.4188254,1.70881568,1.316437011372444,77.03797587885218,,5.386405,2.583961,,,5.516322,4.495562666666666,1.6567695391104742,36.85344109192281,,2.459945,3.861227,3.130836,2.664682,4.383809,3.3000998,0.8104868085377456,24.559463581608824,,6.429445,3.61166,3.107372,2.625817,4.931927,4.1412442,1.5416641123035526,37.22707567700433,,6.191323,3.711043,3.307125,2.791503,4.252559,4.0507106,1.3111885473236866,32.369346438219665,,8.501356,6.001993,10.31227,6.180362,7.74899525,2.053375373755673,26.498601528445548,,5.806409,5.472285,6.167523,4.483469,1.760216,4.7379804000000005,1.778777096682662,37.54293911141257,,5.003536,5.636861,4.774235,5.645293,-2.221393,3.7677064,3.370042900510882,89.44547538287172,
+11,3.740245,2.080393,,0.2708296,,2.0304892,1.735245975756786,85.4595028506818,,4.446393,6.11115,5.104506,4.735899,4.781292,5.035848,0.6448282075347669,12.804759149497105,,4.02871,4.009587,5.759967,3.06436,1.229087,2.486529,3.4297066666666667,1.548610256358993,45.15284853395605,,5.615928,9.599972,5.95135,4.018443,3.028037,4.631933,5.474277166666667,2.2839487329468158,41.72146684230699,,4.058403,0,0,,5.471172,2.3823937500000003,2.810762532590089,117.98060386072153,,4.179026,5.418031,4.278059,4.051464,0.3846287,3.6622417400000002,1.9120234048179532,52.20909870406187,,1.295455,1.604261,9.598935,,1.321902,3.45513825,4.098248151691271,118.61314526824711,,2.699774,1.478293,2.644482,2.847978,1.885295,2.3111644,0.5969351722802905,25.828330181976256,,4.702738,1.804498,1.61727,2.03718,2.726338,2.5776048,1.2599909423560156,48.882239137513075,,3.53512,2.024735,0,2.289491,1.925745,1.9550182,1.268503770892582,64.88449933062424,,4.000076,3.506441,1.503308,2.33948,2.698667,2.8095944,0.980119663593839,34.884738651025174,,2.474415,2.4721,5.882982,1.669194,0.874815,2.6747012,1.912123332973242,71.48923150642929,,9.470068,3.560443,,,8.033844,7.021451666666667,3.0821454520512708,43.8961285838271,,2.890385,5.567244,4.630435,3.837245,6.945757,4.7742132,1.564599836283131,32.771888701642624,,10.9377,5.78016,4.265481,5.388308,7.160444,6.7064186,2.5818321142568115,38.497926661732855,,9.596511,5.696442,5.794175,4.79989,7.638964,6.7051964,1.9176391706758336,28.599299055219824,,12.92765,8.235493,13.48496,8.211935,10.7150095,2.8856996714264977,26.93137762898388,,9.269642,10.3357,10.07243,8.349841,4.832891,8.5721008,2.229289288059246,26.00633543715732,,8.941649,9.623076,10.47854,10.13736,2.531106,8.3423462,3.299823624913186,39.55510291473142,
diff --git a/tests/data/live_cell_imaging/test.txt b/tests/data/live_cell_imaging/test.txt
new file mode 100644
index 0000000..bc5f6b8
--- /dev/null
+++ b/tests/data/live_cell_imaging/test.txt
@@ -0,0 +1,12 @@
+Vessel Name: 220727_2%FCS_X_C55_C56_C57_C58
+Metric: Relative Wound Density (%)
+Cell Type: X
+Passage: 24
+Notes: C55_C56_C57_C58
+Analysis: X_Wounding_CS_V2
+
+Date Time Elapsed CA 10 µM (A1) CA 10 µM (A2) CA 10 µM (A3) CA 10 µM (A4) CA 10 µM (A5) CC 10 µM (A6) CC 10 µM (A7) CC 10 µM (A8) CC 10 µM (A9) CC 10 µM (A10) DMSO 0.05% (A11) DMSO 0.05% (B11) DMSO 0.05% (C11) DMSO 0.05% (D11) DMSO 0.05% (E11) DMSO 0.05% (F11) UT 100% (A12) UT 100% (B12) UT 100% (C12) UT 100% (D12) UT 100% (E12) UT 100% (F12) CA 1 µM (B1) CA 1 µM (B2) CA 1 µM (B3) CA 1 µM (B4) CA 1 µM (B5) CC 1 µM (B6) CC 1 µM (B7) CC 1 µM (B8) CC 1 µM (B9) CC 1 µM (B10) CA 0.1 µM (C1) CA 0.1 µM (C2) CA 0.1 µM (C3) CA 0.1 µM (C4) CA 0.1 µM (C5) CC 0.1 µM (C6) CC 0.1 µM (C7) CC 0.1 µM (C8) CC 0.1 µM (C9) CC 0.1 µM (C10) CA 0.01 µM (D1) CA 0.01 µM (D2) CA 0.01 µM (D3) CA 0.01 µM (D4) CA 0.01 µM (D5) CC 0.01 µM (D6) CC 0.01 µM (D7) CC 0.01 µM (D8) CC 0.01 µM (D9) CC 0.01 µM (D10) CB 10 µM (E1) CB 10 µM (E2) CB 10 µM (E3) CB 10 µM (E4) CB 10 µM (E5) CD 10 µM (E6) CD 10 µM (E7) CD 10 µM (E8) CD 10 µM (E9) CD 10 µM (E10) CB 1 µM (F1) CB 1 µM (F2) CB 1 µM (F3) CB 1 µM (F4) CB 1 µM (F5) CD 1 µM (F6) CD 1 µM (F7) CD 1 µM (F8) CD 1 µM (F9) CD 1 µM (F10) CB 0.1 µM (G1) CB 0.1 µM (G2) CB 0.1 µM (G3) CB 0.1 µM (G4) CB 0.1 µM (G5) CD 0.1 µM (G6) CD 0.1 µM (G7) CD 0.1 µM (G8) CD 0.1 µM (G9) CD 0.1 µM (G10) Pos 10 µM (G11) Pos 10 µM (G12) Pos 10 µM (H11) Pos 10 µM (H12) CB 0.01 µM (H1) CB 0.01 µM (H2) CB 0.01 µM (H3) CB 0.01 µM (H4) CB 0.01 µM (H5) CD 0.01 µM (H6) CD 0.01 µM (H7) CD 0.01 µM (H8) CD 0.01 µM (H9) CD 0.01 µM (H10)
+27/07/2022 18:00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+27/07/2022 21:00 3 2.941424 0.7709512 -0.9661244 1.2095 1.907017 1.891028 1.445611 2.349506 1.624458 1.587884 2.080587 1.17492 0.4584868 0.849259 2.211427 3.804555 2.52322 1.118516 1.60945 2.483132 2.296167 0 0 1.857243 2.125729 2.373146 1.194392 0.8878424 -0.1615143 0.6991959 0.5156834 5.149718 0.6990805 0.9538784 0.6376827 0.8849707 1.343013 0.3406399 1.909729 1.011549 -0.3114207 1.171259 0.5547474 1.48487 0.1732116 0 0.4102185 0.778515 1.776656 0.1189434 0.7330513 0.4719042 0.7252991 0.4734694 0.8170961 2.897962 0.5366114 0.4626927 3.35836 1.302759 2.761429 1.018728 1.988602 1.417326 1.585365 2.739432 4.537059 1.258467 0.985615 1.610166 3.046306 3.7115 1.443673 0.8639878 1.5654 3.624008 5.149839 3.571585 7.690483 3.238868 3.952368 3.987249 3.654827 3.378263 3.771674 2.597566 3.637967 3.37047 3.792182 3.945292
+28/07/2022 0:00 6 3.439121 1.6205 0.08946762 3.070065 4.391799 3.2835 2.698675 3.589451 2.745719 2.628779 4.241597 2.058636 0.5669807 1.397869 3.886579 6.691884 4.031245 3.079788 1.979 3.509718 3.066563 0 0 3.644812 3.306175 3.838465 2.640489 3.025772 0.1791517 1.056791 1.143308 7.459068 1.061978 1.937168 1.175532 2.306213 2.372698 1.178732 3.314485 1.402258 0.9818405 2.02676 1.598561 2.414337 1.259886 0 1.62955 1.222111 2.608018 1.932287 1.126612 2.181001 1.848864 1.295691 1.538294 3.932674 1.358594 0.4188254 5.386405 2.583961 5.516322 2.459945 3.861227 3.130836 2.664682 4.383809 6.429445 3.61166 3.107372 2.625817 4.931927 6.191323 3.711043 3.307125 2.791503 4.252559 8.501356 6.001993 10.31227 6.180362 5.806409 5.472285 6.167523 4.483469 1.760216 5.003536 5.636861 4.774235 5.645293 -2.221393
+28/07/2022 3:00 9 3.740245 2.080393 0.2708296 4.446393 6.11115 5.104506 4.735899 4.781292 4.02871 4.009587 5.759967 3.06436 1.229087 2.486529 5.615928 9.599972 5.95135 4.018443 3.028037 4.631933 4.058403 0 0 5.471172 4.179026 5.418031 4.278059 4.051464 0.3846287 1.295455 1.604261 9.598935 1.321902 2.699774 1.478293 2.644482 2.847978 1.885295 4.702738 1.804498 1.61727 2.03718 2.726338 3.53512 2.024735 0 2.289491 1.925745 4.000076 3.506441 1.503308 2.33948 2.698667 2.474415 2.4721 5.882982 1.669194 0.874815 9.470068 3.560443 8.033844 2.890385 5.567244 4.630435 3.837245 6.945757 10.9377 5.78016 4.265481 5.388308 7.160444 9.596511 5.696442 5.794175 4.79989 7.638964 12.92765 8.235493 13.48496 8.211935 9.269642 10.3357 10.07243 8.349841 4.832891 8.941649 9.623076 10.47854 10.13736 2.531106
diff --git a/tests/data/live_cell_imaging/test.xlsx b/tests/data/live_cell_imaging/test.xlsx
new file mode 100644
index 0000000..7680941
Binary files /dev/null and b/tests/data/live_cell_imaging/test.xlsx differ
diff --git a/tests/data/live_cell_imaging/time_df.csv b/tests/data/live_cell_imaging/time_df.csv
new file mode 100644
index 0000000..ef6f874
--- /dev/null
+++ b/tests/data/live_cell_imaging/time_df.csv
@@ -0,0 +1,5 @@
+,Date Time,Elapsed
+8,27/07/2022 18:00,0
+9,27/07/2022 21:00,3
+10,28/07/2022 0:00,6
+11,28/07/2022 3:00,9
diff --git a/tests/data/root_directory/image1.jpg b/tests/data/root_directory/image1.jpg
new file mode 100644
index 0000000..02b045c
Binary files /dev/null and b/tests/data/root_directory/image1.jpg differ
diff --git a/tests/data/root_directory/image2.jpg b/tests/data/root_directory/image2.jpg
new file mode 100644
index 0000000..2011b4e
Binary files /dev/null and b/tests/data/root_directory/image2.jpg differ
diff --git a/tests/data/root_directory/subdirectory1/file.txt b/tests/data/root_directory/subdirectory1/file.txt
new file mode 100644
index 0000000..e69de29
diff --git a/tests/data/root_directory/subdirectory2/subdirectory4/file.txt b/tests/data/root_directory/subdirectory2/subdirectory4/file.txt
new file mode 100644
index 0000000..e69de29
diff --git a/tests/data/subimage/file.csv b/tests/data/subimage/file.csv
new file mode 100644
index 0000000..e69de29
diff --git a/tests/data/subimage/file.txt b/tests/data/subimage/file.txt
new file mode 100644
index 0000000..e69de29
diff --git a/tests/data/subimage/subimage.png b/tests/data/subimage/subimage.png
new file mode 100644
index 0000000..6fbbf09
Binary files /dev/null and b/tests/data/subimage/subimage.png differ
diff --git a/tests/data/tight_junctions.tiff b/tests/data/tight_junctions.tiff
new file mode 100644
index 0000000..76d9a18
Binary files /dev/null and b/tests/data/tight_junctions.tiff differ
diff --git a/tests/data/tissue_area.tif b/tests/data/tissue_area.tif
new file mode 100644
index 0000000..a7ee9cc
Binary files /dev/null and b/tests/data/tissue_area.tif differ
diff --git a/tests/data/tissue_boundary.pickle b/tests/data/tissue_boundary.pickle
new file mode 100644
index 0000000..658626c
Binary files /dev/null and b/tests/data/tissue_boundary.pickle differ
diff --git a/tests/test_cli.py b/tests/test_cli.py
new file mode 100644
index 0000000..3790200
--- /dev/null
+++ b/tests/test_cli.py
@@ -0,0 +1,5 @@
+import subprocess
+
+
+def test_cli() -> None:
+ assert 'help' in subprocess.check_output(['bimana', '-h'], text=True)
diff --git a/tests/test_histological_section/__init__.py b/tests/test_histological_section/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_histological_section/test_analysis.py b/tests/test_histological_section/test_analysis.py
new file mode 100644
index 0000000..0900bb4
--- /dev/null
+++ b/tests/test_histological_section/test_analysis.py
@@ -0,0 +1,113 @@
+import pickle
+from pathlib import Path
+from shutil import copy2
+from typing import Any
+
+import cv2
+import numpy as np
+import numpy.typing as npt
+import pytest
+
+from bimana.histological_section.analysis import (
+ amount_cilia_above_tissue_area, amount_staining_in_tissue_area,
+ crop_and_save_tissue_sections, tissue_boundary)
+from tests import SUBIMG_PTH, TEST_IMG_PTH, TEST_TISS_BNDY_PTH
+
+
+@pytest.fixture(scope='module')
+def img() -> npt.NDArray[Any]:
+ return cv2.imread(TEST_IMG_PTH)
+
+
+@pytest.fixture
+def tiss_bndy() -> None:
+ with open(TEST_TISS_BNDY_PTH, 'rb') as f:
+ return pickle.load(f)
+
+
+def test_amount_staining_in_tissue_areae(
+ img: npt.NDArray[Any],
+ tiss_bndy: list[list[npt.NDArray[Any]]],
+ tmp_path: Path,
+) -> None:
+ upper_lower_xs, upper_lower_ys = tiss_bndy
+ stain_lower_bgr = np.array([0, 0, 0])
+ stain_upper_bgr = np.array([255, 255, 150])
+
+ pct_stn, stn_amt, tiss_size, procd_imgs = amount_staining_in_tissue_area(
+ img, [upper_lower_xs], [upper_lower_ys], stain_lower_bgr,
+ stain_upper_bgr)
+
+ assert 10 < pct_stn < 25
+ assert 10 < (stn_amt / tiss_size) * 100 < 25
+ assert tiss_size > stn_amt
+
+ for name, procd_img in procd_imgs:
+ assert cv2.imwrite(str(tmp_path / f'{name}.png'), procd_img)
+
+
+def test_amount_cilia_above_tissue_area(
+ img: npt.NDArray[Any],
+ tiss_bndy: list[list[npt.NDArray[Any]]],
+ tmp_path: Path,
+) -> None:
+ upper_lower_xs, upper_lower_ys = tiss_bndy
+ cilia_lower_bgr = np.array([220, 220, 220])
+ cilia_upper_bgr = np.array([245, 245, 245])
+ thickness = 15
+
+ pct_cil, cil_amt, reg_size, procd_imgs = amount_cilia_above_tissue_area(
+ img, [upper_lower_xs], [upper_lower_ys], cilia_lower_bgr,
+ cilia_upper_bgr, thickness)
+
+ assert 20 < pct_cil < 35
+ assert 20 < (cil_amt / reg_size) * 100 < 35
+ assert reg_size > cil_amt
+
+ for name, procd_img in procd_imgs:
+ assert cv2.imwrite(str(tmp_path / f'{name}.png'), procd_img)
+
+
+@pytest.mark.parametrize(
+ 'iso_non_tissue_sens,smooth_segmented_tissue_boundary',
+ [(0.2, True), (None, False)]
+)
+def test_tissue_boundary(
+ iso_non_tissue_sens: float | None,
+ smooth_segmented_tissue_boundary: bool,
+ img: npt.NDArray[Any],
+ tmp_path: Path,
+) -> None:
+ # TODO compare outputs of the different inputs?
+ non_tissue_stain_lower_bgr = np.array([210, 210, 210])
+ non_tissue_stain_upper_bgr = np.array([255, 255, 150])
+
+ (upper_lower_xs, upper_lower_ys), procd_imgs = tissue_boundary(
+ img, non_tissue_stain_lower_bgr, non_tissue_stain_upper_bgr,
+ iso_non_tissue_sens=iso_non_tissue_sens,
+ smooth_segmented_tissue_boundary=smooth_segmented_tissue_boundary)
+
+ upper_lower_xs, upper_lower_ys = upper_lower_xs[0], upper_lower_ys[0]
+ assert len(upper_lower_xs[0]) == len(upper_lower_ys[0])
+ assert len(upper_lower_xs[1]) == len(upper_lower_ys[1])
+
+ assert len(upper_lower_xs[0]) > 2
+ assert len(upper_lower_xs[1]) > 2
+
+ assert np.all(upper_lower_ys[0] < upper_lower_ys[1])
+
+ for name, procd_img in procd_imgs:
+ assert cv2.imwrite(str(tmp_path / f'{name}.png'), procd_img)
+
+
+def test_crop_and_save_tissue_sections(tmp_path: Path) -> None:
+ # TODO Check image contents?
+ subimg_path = Path(SUBIMG_PTH)
+ copy2(subimg_path, tmp_path / subimg_path.name)
+
+ dirs = crop_and_save_tissue_sections(tmp_path, 2)
+
+ files = [f for d in dirs for f in d.iterdir()]
+ assert len(files) == 2
+ for f in files:
+ assert f.is_file()
diff --git a/tests/test_histological_section/test_commands.py b/tests/test_histological_section/test_commands.py
new file mode 100644
index 0000000..ee5bb79
--- /dev/null
+++ b/tests/test_histological_section/test_commands.py
@@ -0,0 +1,37 @@
+import shutil
+from pathlib import Path
+
+from bimana.histological_section.commands import (
+ METRICS_CSV_FILENAME, histological_section_analysis)
+from tests import HIST_SECT_IMG_DIR_PTH
+
+
+def test_histological_section_analysis(tmp_path: Path) -> None:
+ root_dir = tmp_path / 'root_dir'
+ shutil.copytree(HIST_SECT_IMG_DIR_PTH, root_dir)
+ img_filename = list(root_dir.iterdir())[0].name
+ # TODO dirname hardcoded?
+ output_dir = root_dir / str(img_filename).replace('.', '_')
+ amount_staining = amount_cilia = True
+
+ histological_section_analysis.callback(root_dir, False, False)
+
+ assert not output_dir.is_dir()
+ assert len(list(root_dir.iterdir())) == 1
+
+ non_tissue_lower_bgr_str = ('x', '10', '10')
+ histological_section_analysis.callback(
+ root_dir, amount_staining, amount_cilia,
+ non_tissue_lower_colour_limit=non_tissue_lower_bgr_str)
+
+ assert not output_dir.is_dir()
+ assert len(list(root_dir.iterdir())) == 1
+
+ histological_section_analysis.callback(
+ root_dir, amount_staining, amount_cilia)
+
+ assert (output_dir.parent / img_filename).is_file()
+ assert output_dir.is_dir()
+ assert len([f for f in output_dir.iterdir() if f.is_file()]) > 2
+ assert METRICS_CSV_FILENAME in [f.name for f in
+ output_dir.parent.iterdir()]
diff --git a/tests/test_live_cell_imaging/__init__.py b/tests/test_live_cell_imaging/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_live_cell_imaging/test_metrics_file_processing.py b/tests/test_live_cell_imaging/test_metrics_file_processing.py
new file mode 100644
index 0000000..67f95e0
--- /dev/null
+++ b/tests/test_live_cell_imaging/test_metrics_file_processing.py
@@ -0,0 +1,249 @@
+import pickle
+from csv import DictReader
+from pathlib import Path
+from shutil import copy2
+
+import cv2
+import numpy as np
+import pandas as pd
+import pytest
+from bimana.live_cell_imaging.metrics_file_processing import (
+ MetricsTxtFileProcessor, metrics_file_processing)
+from tests import (COMPDS_DF, CTRL_DF, METRICS_DF_PATH, DFS_PATH, FIGURES_DIR,
+ FLD_CHG_DF, FLD_CHG_STATS_DF, GEND_EXCEL, INFO_DF_PATH,
+ METRICS_TXT_FILE_PATH, NOTES_COMPDS_DF_PATH, STATS_DF,
+ TIME_DF_PATH)
+
+
+def load_csv(
+ csv_path: str,
+ skip_header: bool = False,
+ skip_index_col: bool = False,
+) -> pd.DataFrame:
+ df = pd.read_csv(csv_path, index_col=None if skip_index_col else 0,
+ header=None if skip_header else 'infer')
+ if not skip_header:
+ with open(csv_path, encoding='utf-8') as f:
+ if (cols := DictReader(f).fieldnames) is not None:
+ df.columns = cols if skip_index_col else cols[1:]
+
+ if '' in df.columns:
+ df[''] = ''
+
+ return df
+
+
+@pytest.fixture(scope='module')
+def processor() -> MetricsTxtFileProcessor:
+ return MetricsTxtFileProcessor(Path(METRICS_TXT_FILE_PATH))
+
+
+@pytest.fixture(scope='module')
+def metrics_df() -> pd.DataFrame:
+ return load_csv(METRICS_DF_PATH)
+
+
+@pytest.fixture(scope='module')
+def info_df() -> pd.DataFrame:
+ return load_csv(INFO_DF_PATH, True, True)
+
+
+@pytest.fixture(scope='module')
+def time_df() -> pd.DataFrame:
+ return load_csv(TIME_DF_PATH)
+
+
+@pytest.fixture(scope='module')
+def stats_df() -> pd.DataFrame:
+ return load_csv(STATS_DF)
+
+
+@pytest.fixture(scope='module')
+def fld_chg_df() -> pd.DataFrame:
+ return load_csv(FLD_CHG_DF)
+
+
+@pytest.fixture(scope='module')
+def fld_chg_stats_df() -> pd.DataFrame:
+ return load_csv(FLD_CHG_STATS_DF)
+
+
+@pytest.fixture(scope='module')
+def ctrl_df() -> pd.DataFrame:
+ return load_csv(CTRL_DF)
+
+
+@pytest.fixture(scope='module')
+def notes_cmpds_df() -> pd.DataFrame:
+ return load_csv(NOTES_COMPDS_DF_PATH)
+
+
+@pytest.fixture(scope='module')
+def compds_df() -> pd.DataFrame:
+ return load_csv(COMPDS_DF)
+
+
+@pytest.fixture(scope='module')
+def dfs() -> pd.DataFrame:
+ with open(DFS_PATH, 'rb') as f:
+ return pickle.load(f)
+
+
+def test_create_dataframes(
+ processor: MetricsTxtFileProcessor,
+ metrics_df: pd.DataFrame,
+ info_df: pd.DataFrame,
+ time_df: pd.DataFrame,
+) -> None:
+ procd_metrics_df, procd_df_info, procd_df_time = (
+ processor.create_dataframes())
+
+ assert procd_metrics_df.equals(metrics_df)
+ assert procd_df_info.equals(info_df)
+ assert procd_df_time.equals(time_df)
+
+
+def test_get_compound_dataframe(
+ processor: MetricsTxtFileProcessor,
+ stats_df: pd.DataFrame,
+ ctrl_df: pd.DataFrame,
+) -> None:
+ vehicle_control = 'DMSO 0.05%'
+
+ procd_df_ctrl = processor.get_compound_dataframe(stats_df, vehicle_control)
+
+ assert procd_df_ctrl.equals(ctrl_df)
+
+
+def test_use_notes_compounds(
+ processor: MetricsTxtFileProcessor,
+ metrics_df: pd.DataFrame,
+ info_df: pd.DataFrame,
+ notes_cmpds_df: pd.DataFrame,
+) -> None:
+ placeholder_compounds = ['CA', 'CB', 'CC', 'CD']
+
+ procd_notes_cmpd_df = processor.use_notes_compounds(metrics_df, info_df,
+ placeholder_compounds)
+
+ assert procd_notes_cmpd_df.equals(notes_cmpds_df)
+
+
+def test_compute_stats(
+ processor: MetricsTxtFileProcessor,
+ metrics_df: pd.DataFrame,
+ stats_df: pd.DataFrame,
+) -> None:
+ procd_stats_df = processor.compute_stats(metrics_df)
+
+ assert procd_stats_df.round(5).equals(stats_df.round(5))
+
+
+def test_compute_fold_changes(
+ processor: MetricsTxtFileProcessor,
+ metrics_df: pd.DataFrame,
+ ctrl_df: pd.DataFrame,
+ fld_chg_df: pd.DataFrame,
+) -> None:
+ procd_fld_chg_df = processor.compute_fold_changes(metrics_df, ctrl_df)
+
+ assert procd_fld_chg_df.round(5).equals(fld_chg_df.round(5))
+
+
+def test_get_timepoints_dataframe(
+ processor: MetricsTxtFileProcessor,
+ time_df: pd.DataFrame,
+ fld_chg_df: pd.DataFrame,
+ compds_df: pd.DataFrame,
+) -> None:
+ fig_tpts = [6]
+
+ procd_df_compds = processor.get_timepoints_dataframe(fld_chg_df,
+ time_df, fig_tpts)
+
+ assert procd_df_compds.equals(compds_df)
+
+
+def test_split_dataframe(
+ processor: MetricsTxtFileProcessor,
+ compds_df: pd.DataFrame,
+ dfs: pd.DataFrame,
+) -> None:
+ procd_dfs = processor.split_dataframe(compds_df)
+
+ for (procd_compd, procd_v), (compd, v) in zip(procd_dfs.items(),
+ dfs.items()):
+ assert procd_compd == compd
+ for (procd_conc, procd_df), (conc, df) in zip(procd_v.items(),
+ v.items()):
+ assert procd_conc == conc
+ assert procd_df.round(5).equals(df.round(5))
+
+
+def test_gen_analysed_excel(
+ processor: MetricsTxtFileProcessor,
+ stats_df: pd.DataFrame,
+ fld_chg_stats_df: pd.DataFrame,
+ time_df: pd.DataFrame,
+ info_df: pd.DataFrame,
+ tmp_path: Path,
+) -> None:
+ processor.stats_df = stats_df
+ processor.fld_chg_stats_df = fld_chg_stats_df
+ processor.time_df = time_df
+ processor.info_df = info_df
+
+ processor.gen_analysed_excel(tmp_path / 'test.xlsx')
+
+ files = [f for f in tmp_path.iterdir() if f.is_file()]
+ assert len(files) == 1
+
+ excel = pd.read_excel(files[0])
+ expected_excel = pd.read_excel(GEND_EXCEL)
+
+ for df in [excel, expected_excel]:
+ df.iloc[7:11, 1:] = df.iloc[7:11, 1:].astype(float).round(5)
+ df.iloc[13:17, 1:] = df.iloc[13:17, 1:].astype(float).round(5)
+
+ assert excel.equals(expected_excel)
+
+
+def test_generate_compound_summary_figs(
+ processor: MetricsTxtFileProcessor,
+ dfs: pd.DataFrame,
+ tmp_path: Path,
+) -> None:
+ vehicle_control = 'DMSO'
+ positive_control = 'Pos'
+ negative_control = 'UT'
+ threshold = 120
+ processor.dfs = dfs
+
+ processor.generate_compound_summary_figs(
+ vehicle_control, positive_control, negative_control, threshold,
+ tmp_path)
+
+ files = sorted([f for f in tmp_path.iterdir() if f.is_file()])
+ assert len(files) == 4
+
+ expected_files = sorted([f for f in Path(FIGURES_DIR).iterdir() if
+ f.is_file()])
+
+ for f, expected_f in zip(files, expected_files):
+ assert np.array_equal(cv2.imread(str(f)), cv2.imread(str(expected_f)))
+
+
+def test_metrics_file_processing(tmp_path: Path) -> None:
+ copy2(METRICS_TXT_FILE_PATH, tmp_path)
+
+ fig_tpts = 'fail'
+ metrics_file_processing.callback(tmp_path, figure_timepoints=fig_tpts)
+
+ assert len(list(tmp_path.iterdir())) == 1
+
+ metrics_file_processing.callback(tmp_path)
+
+ dirs = [d for d in tmp_path.iterdir() if d.is_dir()]
+
+ assert len(dirs) == 1
+ assert len([f for f in dirs[0].iterdir() if f.is_file()]) == 5
diff --git a/tests/test_tight_junctions/__init__.py b/tests/test_tight_junctions/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_tight_junctions/test_analysis.py b/tests/test_tight_junctions/test_analysis.py
new file mode 100644
index 0000000..c3dbdb6
--- /dev/null
+++ b/tests/test_tight_junctions/test_analysis.py
@@ -0,0 +1,49 @@
+from pathlib import Path
+
+import cv2
+import pytest
+import numpy as np
+import numpy.typing as npt
+from bimana.tight_junctions.analysis import (extract_tight_junctions,
+ perform_ijoq, segment_cells)
+from bimana.utils.image_processing import MAX_PX_VAL, ImageChannel
+from tests import BIN_TGHT_JNCS_PTH, TIGHT_JUNCS_IMG_PTH
+
+
+@pytest.fixture(scope='module')
+def img() -> npt.NDArray[np.uint8]:
+ return cv2.imread(TIGHT_JUNCS_IMG_PTH)
+
+
+@pytest.fixture
+def bin_tght_jncs_img() -> npt.NDArray[np.bool_]:
+ return (cv2.imread(BIN_TGHT_JNCS_PTH,
+ cv2.IMREAD_GRAYSCALE) / MAX_PX_VAL).astype(bool)
+
+
+def test_extract_tight_junctions(
+ img: npt.NDArray[np.uint8],
+ tmp_path: Path,
+) -> None:
+ tight_juncs, procd_imgs = extract_tight_junctions(img, ImageChannel.GREEN)
+
+ assert len(np.unique(tight_juncs)) == 2
+
+ for name, procd_img in procd_imgs:
+ assert cv2.imwrite(str(tmp_path / f'{name}.png'), procd_img)
+
+
+def test_segment_cells(
+ img: npt.NDArray[np.uint8],
+ tmp_path: Path,
+) -> None:
+ cells, procd_imgs = segment_cells(img, ImageChannel.BLUE)
+
+ assert len(cells) == 5
+
+ for name, procd_img in procd_imgs:
+ assert cv2.imwrite(str(tmp_path / f'{name}.png'), procd_img)
+
+
+def test_perform_ijoq(bin_tght_jncs_img: npt.NDArray[np.bool_]) -> None:
+ assert perform_ijoq(bin_tght_jncs_img) == 0.0316
diff --git a/tests/test_tight_junctions/test_commands.py b/tests/test_tight_junctions/test_commands.py
new file mode 100644
index 0000000..2f5c214
--- /dev/null
+++ b/tests/test_tight_junctions/test_commands.py
@@ -0,0 +1,30 @@
+import shutil
+from pathlib import Path
+
+from bimana.tight_junctions.commands import (METRICS_CSV_FILENAME,
+ tight_junction_analysis)
+from tests import TIGHT_JUNCS_IMG_PTH
+
+
+def test_tight_junction_analysis(tmp_path: Path) -> None:
+ root_dir = tmp_path / 'root_dir'
+ root_dir.mkdir()
+ shutil.copy2(TIGHT_JUNCS_IMG_PTH, root_dir)
+ img_filename = list(root_dir.iterdir())[0].name
+ # TODO dirname hardcoded?
+ output_dir = root_dir / str(img_filename).replace('.', '_')
+ analyse_tight_juncs = analyse_cells = True
+
+ tight_junction_analysis.callback(root_dir, False, False)
+
+ assert not output_dir.is_dir()
+ assert len(list(root_dir.iterdir())) == 1
+
+ tight_junction_analysis.callback(
+ root_dir, analyse_tight_juncs, analyse_cells)
+
+ assert (output_dir.parent / img_filename).is_file()
+ assert output_dir.is_dir()
+ assert len([f for f in output_dir.iterdir() if f.is_file()]) > 2
+ assert METRICS_CSV_FILENAME in [f.name for f in
+ output_dir.parent.iterdir()]
diff --git a/tests/test_utils/__init__.py b/tests/test_utils/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_utils/test_commands.py b/tests/test_utils/test_commands.py
new file mode 100644
index 0000000..8ee537e
--- /dev/null
+++ b/tests/test_utils/test_commands.py
@@ -0,0 +1,9 @@
+from bimana.utils.commands import parse_input_bgr
+
+
+def test_parse_input_bgr() -> None:
+ input_bgr = ('0.3', '255', '0.0')
+ output_bgr = parse_input_bgr(input_bgr)
+ expected_result = (0.3, 255, 0.0)
+
+ assert output_bgr == expected_result
diff --git a/tests/test_utils/test_deep_learning/__init__.py b/tests/test_utils/test_deep_learning/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_utils/test_deep_learning/test_dexined.py b/tests/test_utils/test_deep_learning/test_dexined.py
new file mode 100644
index 0000000..808d4cd
--- /dev/null
+++ b/tests/test_utils/test_deep_learning/test_dexined.py
@@ -0,0 +1,19 @@
+import cv2
+import numpy as np
+import numpy.typing as npt
+import pytest
+
+from bimana.utils.deep_learning.dexined import detect_edges
+from tests import LENA_IMG_PTH
+
+
+@pytest.fixture()
+def lena_img() -> npt.NDArray[np.uint8]:
+ return cv2.imread(LENA_IMG_PTH, cv2.IMREAD_GRAYSCALE)
+
+
+def test_detect_edges(lena_img: npt.NDArray[np.uint8]) -> None:
+ edges = detect_edges(lena_img)
+
+ assert len(edges.shape) == 2
+ assert np.array_equal(range(0, 249), np.unique(edges))
diff --git a/tests/test_utils/test_file_processing.py b/tests/test_utils/test_file_processing.py
new file mode 100644
index 0000000..797faa1
--- /dev/null
+++ b/tests/test_utils/test_file_processing.py
@@ -0,0 +1,93 @@
+import csv
+from collections import defaultdict
+from pathlib import Path
+from shutil import copy2
+
+import cv2
+import pytest
+import numpy as np
+import numpy.typing as npt
+from bimana.utils.file_processing import (IMAGE_FEX, DirFormat,
+ crop_and_save_images, get_dirs,
+ load_imgs, save_imgs, save_csv)
+from tests import ROOT_DIR_PTH, SUBIMG_PTH
+
+
+@pytest.fixture()
+def subimg() -> npt.NDArray[np.uint8]:
+ return cv2.imread(SUBIMG_PTH)
+
+
+@pytest.mark.parametrize(
+ 'flag,num_dirs',
+ [(DirFormat.SUB, 1), (DirFormat.ROOT, 1), (DirFormat.RECURSIVE, 3)]
+)
+def test_get_dirs(flag: DirFormat, num_dirs: int) -> None:
+ dirs = get_dirs(ROOT_DIR_PTH, flag)
+
+ assert len(dirs) == num_dirs
+ for curr_dir in dirs:
+ assert curr_dir.exists()
+
+
+def test_load_imgs_no_shrink() -> None:
+ imgs = load_imgs(ROOT_DIR_PTH)
+ prev_img_num = -1
+ for (path, img) in imgs:
+ assert len(img.shape) == 3
+ assert len(np.unique(img)) > 2
+ assert int(path.stem[-1]) > prev_img_num
+
+
+def test_load_imgs_shrink() -> None:
+ with pytest.warns(UserWarning):
+ imgs = load_imgs(Path(SUBIMG_PTH).parent, 2)
+
+ assert len(imgs) == 1
+ assert imgs[0][1].shape == (50, 50, 3)
+ assert imgs[0][0] == Path(SUBIMG_PTH)
+
+
+def test_save_imgs(tmp_path: Path) -> None:
+ img1 = np.random.randint(0, 255, (50, 50))
+ img2 = np.random.randint(0, 255, (50, 50))
+
+ imgs = [('img1', img1), ('img2', img2)]
+ save_imgs(imgs, tmp_path)
+ for name, _ in imgs:
+ assert (tmp_path / (name + IMAGE_FEX)).is_file()
+
+
+def test_save_csv(tmp_path: Path) -> None:
+ exp_data = {'headerA': [1, 2, 3], 'headerB': [4, 5, 6]}
+ csv_path = tmp_path / 'test.csv'
+
+ save_csv(exp_data, csv_path)
+ assert csv_path.is_file()
+
+ data = defaultdict(list)
+ with open(csv_path, newline='', encoding='utf-8-sig') as f:
+ reader = csv.DictReader(f)
+ headers = reader.fieldnames
+ assert headers is not None
+ for row in reader:
+ for header in headers:
+ data[header].append(int(row[header]))
+
+ assert data == exp_data
+
+
+def test_crop_and_save_images(tmp_path: Path) -> None:
+ # TODO Check image contents?
+ subimg_path = Path(SUBIMG_PTH)
+ input_dir = tmp_path / 'test'
+ input_dir.mkdir()
+ copy2(subimg_path, input_dir / subimg_path.name)
+
+ subimg_coords = np.array([[25, 25, 74, 74], [0, 0, 4, 4]])
+
+ dirs = crop_and_save_images(input_dir / subimg_path.name, subimg_coords)
+ files = [f for d in dirs for f in d.iterdir()]
+ assert len(files) == 2
+ for f in files:
+ assert f.is_file()
diff --git a/tests/test_utils/test_image_processing.py b/tests/test_utils/test_image_processing.py
new file mode 100644
index 0000000..01949a7
--- /dev/null
+++ b/tests/test_utils/test_image_processing.py
@@ -0,0 +1,259 @@
+import cv2
+import numpy as np
+import numpy.typing as npt
+import pytest
+
+from bimana.utils.image_processing import (
+ MAX_PX_VAL, binary_to_bgr_image, auto_segment_image, bound_foreground,
+ bounded_foreground_polyline, centre_coordinates, detect_circular_objects,
+ draw_polyline, extract_channel, ImageChannel, largest_objects,
+ remove_isolated_segmented_objects, scale_bgr_values,
+ smooth_foreground_bounds, segment_image, segment_polyline_bounded_region,
+ segment_region_above_polyline, segment_region_within_image,
+ subimage_coordinates)
+from tests import (CIRCLES_IMG_PTH, GREYSCALE_IMG_PTH, SUBIMG_PTH,
+ TEST_BIN_IMG_PTH, TEST_REF_BIN_IMG_PTH)
+
+
+@pytest.fixture(scope='module')
+def bin_img() -> npt.NDArray[bool]:
+ return (cv2.imread(TEST_BIN_IMG_PTH,
+ cv2.IMREAD_GRAYSCALE) / MAX_PX_VAL).astype(bool)
+
+
+@pytest.fixture
+def refd_bin_img() -> npt.NDArray[bool]:
+ return (cv2.imread(TEST_REF_BIN_IMG_PTH,
+ cv2.IMREAD_GRAYSCALE) / MAX_PX_VAL).astype(bool)
+
+
+@pytest.fixture()
+def grey_img() -> npt.NDArray[np.uint8]:
+ return cv2.imread(GREYSCALE_IMG_PTH, cv2.IMREAD_GRAYSCALE)
+
+
+@pytest.fixture()
+def circles_img() -> npt.NDArray[np.uint8]:
+ return cv2.imread(CIRCLES_IMG_PTH, cv2.IMREAD_GRAYSCALE)
+
+
+@pytest.fixture()
+def subimg() -> npt.NDArray[np.uint8]:
+ return cv2.imread(SUBIMG_PTH)
+
+
+def test_segment_image() -> None:
+ hwc = (10, 20, 3)
+ img, expected_result = np.zeros(hwc), np.zeros(hwc[:2])
+ img[5:, :10] = (210, 210, 210)
+ expected_result[5:, :10] = 1
+ bin_img = segment_image(img, (210, 210, 210), (210, 210, 210))
+
+ assert np.array_equal(bin_img, expected_result)
+
+
+def test_remove_isolated_segmented_objects(bin_img: npt.NDArray[bool]) -> None:
+ threshs = [0.1, 0.2, 0.5]
+ refined_bin_imgs = [remove_isolated_segmented_objects(bin_img, thresh)
+ for thresh in threshs]
+
+ for refined_bin_img in refined_bin_imgs:
+ unique_elements = np.unique(refined_bin_img)
+ assert len(unique_elements) == 2
+ assert unique_elements[0] == 0
+ assert unique_elements[1] == 1
+
+ assert (np.count_nonzero(refined_bin_imgs[2]) < np.count_nonzero(
+ refined_bin_imgs[1]) < np.count_nonzero(refined_bin_imgs[0]))
+
+
+def test_bound_foreground(bin_img: npt.NDArray[bool]) -> None:
+ upper_lower_xs, upper_lower_ys = bound_foreground(bin_img)
+
+ assert len(upper_lower_xs[0]) == len(upper_lower_ys[0])
+ assert len(upper_lower_xs[1]) == len(upper_lower_ys[1])
+
+ assert len(upper_lower_xs[0]) > 2
+ assert len(upper_lower_xs[1]) > 2
+
+ assert np.all(upper_lower_ys[0] < upper_lower_ys[1])
+
+
+def test_bounded_foreground_polyline() -> None:
+ upper_lower_xs = [np.array([0, 1]), np.array([0, 1])]
+ upper_lower_ys = [np.array([10, 20]), np.array([50, 40])]
+ polyline = bounded_foreground_polyline(upper_lower_xs, upper_lower_ys)
+
+ assert np.array_equal(polyline, np.array([[0, 10], [1, 20], [1, 40],
+ [0, 50]]))
+
+
+def test_smooth_foreground_bounds(refd_bin_img: npt.NDArray[bool]) -> None:
+ upper_ys = np.array([43, 43, 42, 43, 42, 42, 43, 43, 43, 43, 43, 43, 43,
+ 43, 43, 45, 44, 44, 46, 66, 66, 45, 44, 43, 44, 44,
+ 44, 45, 44, 44, 45, 45, 45, 45, 44, 44, 44, 44, 44,
+ 44, 44, 44, 45, 46, 46])
+ lower_ys = np.array([133, 132, 124, 125, 127, 126, 133, 134, 135, 136, 135,
+ 136, 136, 136, 136, 135, 135, 138, 138, 120, 117, 117,
+ 117, 117, 116, 120, 135, 137, 137, 137, 137, 137, 137,
+ 136, 138, 137, 128, 126, 93, 95, 95, 136, 136, 136,
+ 136])
+ upper_lower_xs = [np.arange(upper_ys.size), np.arange(lower_ys.size)]
+ upper_lower_ys = [upper_ys, lower_ys]
+
+ refd_upper_lower_xs, refd_upper_lower_ys = smooth_foreground_bounds(
+ refd_bin_img, upper_lower_xs, upper_lower_ys)
+
+ assert len(refd_upper_lower_xs[0]) == len(refd_upper_lower_ys[0])
+ assert len(refd_upper_lower_xs[1]) == len(refd_upper_lower_ys[1])
+
+ assert np.all(refd_upper_lower_ys[0] < 66)
+ assert np.all(refd_upper_lower_ys[1] > 127)
+
+ upper_ys = np.ones((50,), int) * 43
+ lower_ys = np.ones((50,), int) * 133
+ upper_lower_xs = [np.arange(upper_ys.size), np.arange(lower_ys.size)]
+ upper_lower_ys = [upper_ys, lower_ys]
+
+ img = np.zeros((200, 200))
+ polyline = np.array([[0, 43], [upper_ys.size - 1, 43],
+ [lower_ys.size - 1, 133], [0, 133]])
+ cv2.drawContours(img, [polyline], 0, 1, cv2.FILLED)
+
+ refd_upper_lower_xs, refd_upper_lower_ys = smooth_foreground_bounds(
+ img.astype(bool), upper_lower_xs, upper_lower_ys)
+
+ for i in (0, 1):
+ assert np.array_equal(upper_lower_xs[i], refd_upper_lower_xs[i])
+ assert np.array_equal(upper_lower_ys[i], refd_upper_lower_ys[i])
+
+
+def test_segment_polyline_bounded_region() -> None:
+ hw = (10, 20)
+ polyline = np.array([[0, 0], [10, 0], [10, 10], [0, 10]])
+ mask = segment_polyline_bounded_region(polyline, hw)
+
+ assert np.all(mask[:, :11])
+ assert np.all(~mask[:, 11:])
+
+
+def test_segment_region_within_image() -> None:
+ hwc = (10, 20, 3)
+
+ region = np.zeros(hwc[:2], bool)
+ region[5:, :] = 1
+
+ img = np.zeros(hwc)
+ img[:, :10, :] = (255, 0, 0)
+ img[:, 10:20, :] = (0, 0, 255)
+ lower_bgr = upper_bgr = (255, 0, 0)
+
+ produced_result = segment_region_within_image(img, lower_bgr, upper_bgr,
+ region)
+
+ expected_result = np.zeros(hwc[:2], bool)
+ expected_result[5:, :10] = 1
+
+ assert np.array_equal(produced_result, expected_result)
+
+
+def test_segment_region_above_polyline() -> None:
+ hw = (10, 20)
+ height = 3
+
+ upper_ys = np.array([4, 4, 4, 4, 5, 5, 5, 5])
+ upper_xs = np.arange(5, 5 + upper_ys.size)
+ polyline = np.array([[x, y] for x, y in zip(upper_xs, upper_ys)])
+
+ expected_result = np.zeros(hw, bool)
+ expected_result[1:5, 5:9] = 1
+ expected_result[2:6, 9:13] = 1
+
+ mask = segment_region_above_polyline(polyline, height, hw)
+
+ assert np.array_equal(mask, expected_result)
+
+
+def test_draw_polyline() -> None:
+ hwc = (10, 20, 3)
+ img = np.zeros(hwc)
+
+ expected_result = img.copy()
+ expected_result[0, :11] = (0, 255, 0)
+
+ polyline = np.array([[0, 0], [10, 0]])
+ img = draw_polyline(img, polyline, (0, 255, 0), 1)
+
+ assert np.array_equal(expected_result, img)
+
+
+def test_binary_to_bgr_image() -> None:
+ hwc = (10, 20, 3)
+ img = np.zeros(hwc[:2], bool)
+ img[0, :] = 1
+
+ bgr_img = binary_to_bgr_image(img)
+
+ assert bgr_img.shape == (10, 20, 3)
+ assert np.all(bgr_img[0, :] == 255)
+ assert np.all(bgr_img[1:, :] == 0)
+
+
+def test_scale_bgr_values() -> None:
+ expected_result = np.array([210, 210, 210])
+ bgrs = scale_bgr_values((0.823, 210, 0.823))
+
+ assert np.array_equal(expected_result, bgrs)
+
+
+def test_extract_channel() -> None:
+ img = np.zeros((10, 20, 3))
+ img[..., 1] = 1
+ flag = ImageChannel.GREEN
+
+ channel = extract_channel(img, flag)
+ assert np.all(channel) == 1
+
+
+def test_auto_segment_image(grey_img: npt.NDArray[np.uint8]) -> None:
+ bin_img = auto_segment_image(~grey_img)
+
+ assert len(np.unique(bin_img)) == 2
+ assert 0.15 < np.count_nonzero(bin_img) / np.prod(bin_img.shape) < 0.30
+
+
+def test_detect_circular_objects(circles_img: npt.NDArray[np.uint8]) -> None:
+ assert len(detect_circular_objects(circles_img)) == 7
+
+
+def test_centre_coordinates() -> None:
+ contours = [np.array([[[0, 0]], [[10, 0]], [[10, 10]], [[0, 10]]])]
+
+ assert np.array_equal(centre_coordinates(contours)[0], np.array([5, 5]))
+
+
+def test_subimage_coordinates(subimg: npt.NDArray[np.uint8]) -> None:
+ coords = subimage_coordinates(subimg).tolist()
+
+ assert [25, 25, 74, 74] in coords
+ assert [0, 0, 4, 4] in coords
+
+
+@pytest.mark.parametrize('min_area,top_n', [(None, 2), (100, None)])
+def test_largest_objects(min_area: int, top_n: int) -> None:
+ objs = [np.array([[0, 0], [10, 0], [10, 10], [0, 10]]),
+ np.array([[20, 20], [25, 20], [25, 25], [20, 25]]),
+ np.array([[30, 30], [50, 30], [50, 50], [30, 50]])]
+ img = cv2.drawContours(np.zeros((60, 60), np.uint8), objs, -1, 1,
+ cv2.FILLED).astype(bool)
+
+ out_img = np.zeros((60, 60), np.uint8)
+ upper_lower_xs, upper_lower_ys = largest_objects(img, min_area, top_n)
+ for ul_xs, ul_ys in zip(upper_lower_xs, upper_lower_ys):
+ polyline = np.array([[x, y] for x, y in zip(np.append(
+ ul_xs[0], ul_xs[1]), np.append(ul_ys[0], ul_ys[1]))])
+ cv2.drawContours(out_img, [polyline], 0, 1, cv2.FILLED)
+
+ expected_result = cv2.drawContours(img.astype(
+ np.uint8), objs, 1, 0, cv2.FILLED)
+ assert np.array_equal(out_img, expected_result)
diff --git a/tests/test_utils/test_quantification.py b/tests/test_utils/test_quantification.py
new file mode 100644
index 0000000..4e1c593
--- /dev/null
+++ b/tests/test_utils/test_quantification.py
@@ -0,0 +1,131 @@
+from pathlib import Path
+
+import numpy as np
+
+from bimana.utils.quantification import (area, size_connected_components,
+ aspect_ratio, circularity,
+ gen_histogram, gen_stats,
+ nearest_neighbour_distances,
+ num_connected_components,
+ percentage_foreground_in_region,
+ perimeter, roundness, solidity)
+
+
+def test_percentage_foreground_in_region() -> None:
+ hw = (10, 20)
+
+ img = np.zeros(hw, bool)
+ img[5:, 10:] = 1
+
+ region = np.zeros(hw, bool)
+ region[5:, :] = 1
+
+ pct, fg_ct, reg_cnt = percentage_foreground_in_region(img, region)
+ exp_pct, exp_fg_cnt, exp_reg_cnt = 50, 50, 100
+
+ assert (pct, fg_ct, reg_cnt) == (exp_pct, exp_fg_cnt, exp_reg_cnt)
+
+
+def test_nearest_neighbour_distances() -> None:
+ pts = np.array([[3, 4], [6, 8]])
+ dists = nearest_neighbour_distances(pts)
+
+ assert np.all(dists == 5)
+
+
+def test_area() -> None:
+ contours = [np.array([[[0, 0]], [[10, 0]], [[10, 10]], [[0, 10]]])]
+ cnt_areas = area(contours)
+
+ assert cnt_areas[0] == 100
+
+
+def test_perimeter() -> None:
+ contours = [np.array([[[0, 0]], [[10, 0]], [[10, 10]], [[0, 10]]])]
+ cnt_perimeters = perimeter(contours)
+
+ assert cnt_perimeters[0] == 40
+
+
+def test_circularity() -> None:
+ theta = np.linspace(0, 2 * np.pi, 100)
+ radius = 5
+ xs = radius * np.cos(theta)
+ ys = radius * np.sin(theta)
+ contours = [np.array([[[x, y]] for x, y in zip(xs, ys)], dtype=np.float32)]
+
+ cnt_circularity = circularity(contours)
+
+ assert round(cnt_circularity[0], 3) == 1
+
+
+def test_aspect_ratio() -> None:
+ contours = [np.array([[[0, 0]], [[10, 0]], [[10, 10]], [[0, 10]]])]
+ cnt_aspect_ratios = aspect_ratio(contours)
+
+ assert cnt_aspect_ratios[0] == 1
+
+
+def test_solidity() -> None:
+ theta = np.linspace(0, 2 * np.pi, 100)
+ radius = 5
+ xs = radius * np.cos(theta)
+ ys = radius * np.sin(theta)
+ contours = [np.array([[[x, y]] for x, y in zip(xs, ys)], dtype=np.float32)]
+
+ cnt_solidity = solidity(contours)
+
+ assert cnt_solidity[0] == 1
+
+
+def test_roundness() -> None:
+ theta = np.linspace(0, 2 * np.pi, 100)
+ radius = 5
+ xs = radius * np.cos(theta)
+ ys = radius * np.sin(theta)
+ contours = [np.array([[[x, y]] for x, y in zip(xs, ys)], dtype=np.float32)]
+
+ cnt_roundness = roundness(contours)
+
+ assert round(cnt_roundness[0], 2) == 1
+
+
+def test_num_connected_components() -> None:
+ hw = (20, 20)
+ img = np.zeros(hw, bool)
+ img[10, 10] = img[11, 11] = img[12, 12] = 1
+ img[5, 5] = img[5, 6] = img[5, 7] = 1
+
+ num_cnctd_comps = num_connected_components(img)
+
+ assert num_cnctd_comps == 2
+
+
+def test_size_connected_components() -> None:
+ hw = (20, 20)
+ img = np.zeros(hw, bool)
+ img[10, 10] = img[11, 11] = img[12, 12] = 1
+ img[5, 5] = img[5, 6] = img[5, 7] = 1
+
+ size_cnctd_comps = size_connected_components(img)
+
+ assert np.all(size_cnctd_comps == 3)
+
+
+def test_gen_stats() -> None:
+ data = [1, 2, 3]
+
+ metrics = gen_stats(data)
+
+ assert list(metrics.values()) == [1, 3, 2, 1, 1]
+
+
+def test_gen_histogram(tmp_path: Path) -> None:
+ data = {'test': [8, 5, 3, 5, 7, 5, 3, 5, 7, 5]}
+
+ gen_histogram(data, tmp_path)
+
+ files = [f for f in tmp_path.iterdir()]
+
+ assert len(files) == 1
+ assert files[0].is_file()
diff --git a/third_party/DexiNed b/third_party/DexiNed
new file mode 160000
index 0000000..feeb72a
--- /dev/null
+++ b/third_party/DexiNed
@@ -0,0 +1 @@
+Subproject commit feeb72ad55924221bd29f51271864e277301b0ab
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/AUTHORS b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/AUTHORS
new file mode 100644
index 0000000..7d2ea5e
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/AUTHORS
@@ -0,0 +1,28 @@
+Authors of VIPS
+
+See also the files THANKS and ChangeLog
+
+Kirk Martinez and Nicos Dessipris started VIPS in 1990.
+
+John Cupitt started ip in late 1990, and took over maintenance of the VIPS
+library in 1995.
+
+Ruven Pillay, Steve Perry, Lars Raffelt, David Saunders, Jean-Philippe
+Laurant, Ahmed Abood, Helene Chahine, Joe Padfield, Andrey Kiselev, Lev
+Serebryakov, Simon Goodall, Konrad Lang, Markus Wollgarten, Jesper Friis,
+Tom Vajzovic, Chris Leick and others contributed patches for the library
+and ip.
+
+Hans Breuer contributed many win32 compatibility fixes and a win32 build
+system. Dennis Lubert cleaned up the C++ API.
+
+Jose Manuel Menendez Garcia, Javier Alejandre Arenas, and Juan Torres Arjona
+contributed the tmake VIPS.DLL build system and the MSVC project files.
+
+Nicolas Robidoux contributed optimized bilinear and bicubic code to
+the VipsInterpolate class and, with Chantal Racette and Adam Turcotte,
+contributed the novel LBB, Nohalo and VSQBS interpolators.
+
+Lovell Fuller and Kleis Auke Wolthuizen made many contributions and fixes.
+
+Many other active contributors, see https://github.com/libvips/libvips/graphs/contributors
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/COPYING b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/COPYING
new file mode 100644
index 0000000..4362b49
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/COPYING
@@ -0,0 +1,502 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ , 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/ChangeLog b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/ChangeLog
new file mode 100644
index 0000000..88de3b1
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/ChangeLog
@@ -0,0 +1,3764 @@
+11/10/22 started 8.13.3
+- improve rules for 16-bit heifsave [johntrunc]
+- improve libspng pallette write [kleisauke]
+- improve libspng pallette sort [DarthSim]
+- ensure EXIF has prefix before parsing [lovell]
+- fix low bit depth pallette spng save [DarthSim]
+- fix thumbnail of non-sRGB images with an export profile [kleisauke]
+
+5/9/22 started 8.13.2
+- in dzsave, add add missing include directive for errno/EEXIST [kleisauke]
+- fix 8 bit pallete PNG save [lovell]
+- fix null string in buffer print [pclewis]
+- revise caching of seq mode loaders [jcupitt]
+- reduce latency on dzsave kill [kleisauke]
+- improve text too large check [kleisauke]
+- fix subifd writing for small images [ruven]
+- name ICC profiles in spngsave [lovell]
+
+24/7/22 started 8.13.1
+- fix im7 feature detection in meson
+- add a summary table at the end of configure in meson
+- fix libpng fallback when spng is disabled in meson
+- add "unlimited" to jpegload
+- better 0 detection in unpremultiply
+- fix low bitdepth spng save [jeffska]
+- fix PNG low bitdepth save of high bitdepth images
+- add support for libjxl 0.7 [kleisauke]
+- improve compatibility with older libgsf versions [kleisauke]
+
+21/11/21 started 8.13
+- configure fails for requested but unmet dependencies [remicollet]
+- add support for another quantiser [DarthSim]
+- add "extend", "background" and "premultiplied" to vips_mapim() to fix edge
+ antialiasing [GavinJoyce]
+- add support for HDR HEIC and AVIF images
+- add vips_spngsave()
+- jpeg2000 load left-justifies bitdepth
+- add "password" option to pdfload, fix byte ordering of "background"
+- add vips_operation_block_set(), vips_block_untrusted_set()
+- improve the pixel rng
+- new meson build system [tintou]
+- improve introspection annotations [tintou]
+- add "unlimited" to heifload [lovell]
+- add support for regions in C++ API [shado23]
+- add "maxerror" to gifsave [dloebl]
+- update libnsgif API [tlsa]
+- deprecate "properties" option to dzsave (now always on)
+- add vips_dzsave_buffer()
+- always set the min stack size for pthreads, if we can
+- add "fail-on" to thumbnail
+- add "gap" option to vips_reduce[hv]() and vips_resize() [kleisauke]
+- add "ceil" option to vips_shrink() [kleisauke]
+- quality improvements for image resizing [kleisauke]
+- add vips_source_new_from_target()
+- add vips_target_seek(), vips_target_read(), vips_target_new_temp()
+- add vips_tiffsave_target()
+- add vips_target_end(), deprecate vips_target_finish()
+- add "mixed" to webpsave [dloebl]
+- add support for ICC profiles and linear encoding to JXL load and save [f1ac]
+- add "reoptimise" to gifsave [dloebl]
+- add "bitdepth" to magicksave [dloebl]
+- change default PNG filter to "none" [lovell]
+
+26/11/21 started 8.12.3
+- better arg checking for vips_hist_find_ndim() [travisbell]
+- fix thumbnail with CMYK output [AdamGaskins]
+- fix size_t / ssize_t confusion [flga]
+- fix jxl compatibility break [lovell]
+
+26/11/21 started 8.12.2
+- make exif resuint optional and default to inch
+- win: don't set create time on inappropriate file descriptors [lovell]
+- fall back to magicksave for gif if cgif is not present [erik-frontify]
+- fix a crash with 0 length vectors
+- change default frame delay for GIFs from 1s to 0.1s
+- remove stray trailing comma from iiif3 dirnames [whalehub]
+- fix TTF load [chregu]
+- revise GIF save alpha threshold [jfcalvo]
+- raise libpng pixel size limit from 1m to 10m pixels [jskrzypek]
+- fix gif save change detector [TheEssem]
+- fix load from pipe with variable size reads
+
+21/11/21 started 8.12.1
+- fix insert [chregu]
+
+14/6/21 started 8.12
+- all tools support `--version`
+- add vips_svgload_string() convenience function
+- fix thumbnail with small image plus crop plus no upsize [Andrewsville]
+- rename speed / reduction-effort / etc. params as "effort"
+- add gifsave [lovell]
+- arrayjoin minimises inputs during sequential processing, saving a lot of
+ memory and file descriptors
+- add vips_image_get_format_max()
+- flatten handles out of range alpha and max_alpha correctly
+- don't use atexit for cleanup, it's too unreliable
+- tiff writer loops for the whole image rather than per page [LionelArn2]
+- fix VipsSource with named pipes [vibbix]
+- added restart_interval option to jpegsave [manthey]
+- add IIIF3 support to dzsave [martimpassos]
+- add atan2 to math2 [indus]
+- improve buffer and target save file format selection
+- added VipsForeignPpmFormat, format arg to ppm savers
+- add fail-on to give better control over loader error sensitivity
+- add hyperbolic functions sinh, cosh, tanh, asinh, acosh, atanh [hroskes]
+- add untiled jp2k load
+- "insert" will minimise in seq mode
+- better EXIF string handling [lovell]
+
+16/8/21 started 8.11.4
+- fix off-by-one error in new rank fast path
+- add "unlimited" flag to png load [joshuamsager]
+- improve filtering of .v enums [lovell]
+- better logic to prevent shrink to nothing in thumbnail [kleisauke]
+
+14/7/21 started 8.11.3
+- build threadpool later [kleisauke]
+- add jxlsave prototypes [adil-benameur]
+- limit text chunks in PNGs [randy408]
+
+15/6/20 started 8.11.2
+- better libdir guessing [remi]
+- fix tiff pyramid creation with jp2k compression (was broken by 8.11.1)
+- don't load modules if we're built without modules
+
+18/6/21 started 8.11.1
+- add more example code to C docs
+- update libtool support in configure.ac
+- more startup info if VIPS_INFO is set
+- command-line programs set glib prgname (no longer set for you by VIPS_INIT)
+- enable strip chopping for TIFF read [DavidStorm]
+- disable modules by default for static builds [kleisauke]
+- fix jpeg tiff pyramid save
+
+14/8/20 started 8.11
+- add vips_jpegload_source() and vips_svgload_source() to public C API
+- integrate doxygen in build system to generate C++ API docs
+- improve C++ API doc comments
+- add VipsInterpolate and guint64 support to C++ API
+- add VImage::new_from_memory_steal [Zeranoe]
+- vipsthumbnail supports stdin / stdout thumbnailing
+- have a lock just for pdfium [DarthSim]
+- get pdfium load building again [Projkt-James]
+- add _source load support for pdfium
+- add "seed" param to perlin, worley and gaussnoise
+- add vips_source_g_input_stream_new() to load images from a GInputStream
+- add openslideload_source(), vipsload_source(), vipssave_target()
+- add hist path to rank for large windows on uchar images
+- better 8/16-bit choice for pngsave
+- avoid NaN in mapim [afontenot]
+- hist_find outputs a double histogram for large images [erdmann]
+- fix ref leaks in mosaicing package
+- run libvips leak test in CI
+- add vips_fitsload_source(), vips_niftiload_source()
+- png and gif load note background colour as metadata [781545872]
+- add vips_image_[set|get]_array_double()
+- add GIF load with libnsgif
+- add jp2kload, jp2ksave
+- add jp2k compression to tiff load and save
+- add JPEG-XL load and save
+- add black_point_compensation flag for icc transforms
+- add "rgba" flag to vips_text() to enable full colour text rendering
+- move openslide, libheif, poppler and magick to loadable modules [kleisauke]
+- better detection of invalid ICC profiles, better fallback paths
+- add "premultiply" flag to tiffsave
+- new threading model has a singe threadpool shared by all pipelines [kleisauke]
+
+30/4/21 start 8.10.7
+- better vips7 PNG load compatibility [SkyDiverCool]
+- fix load of large PPM images from a pipe [ewelot]
+
+22/12/20 start 8.10.6
+- don't seek on bad file descriptors [kleisauke]
+- check for null memory sources [kleisauke]
+- improve ppmload, fixing a couple of small bugs
+- improve EOF detection in jpegload [bozaro]
+- improve error detection in spngload [randy408]
+- fix includes of glib headers in C++ [lovell]
+- fix build with more modern librsvg [lovell]
+- fix a possible segv with very wide images [f1ac]
+- fix issue thumbnailing RGBA images in linear mode [jjonesrs]
+- improve vipsthumbnail profile handling
+- fix tiff deflate predictor setting [Adios]
+- fix vector path for composite on i386 [kleisauke]
+
+18/12/20 started 8.10.5
+- fix potential /0 in animated webp load [lovell]
+
+14/12/20 started 8.10.4
+- fix spng detection
+
+18/10/20 started 8.10.3
+- relax heic is_a rules [hisham]
+- fix vips7 webp load [barryspearce]
+- fix out of bounds exif read in heifload
+- fix out of bounds read in tiffload
+- fix tiffsave region shrink mode [imgifty]
+- add missing flushes on write to target [harukizaemon]
+- hide info messages you could get with some older glibs [kleisauke]
+- fix --no-strip on dzsave with icc-profiles [altert]
+- better GraphicsMagick image write [bfriesen]
+- add missing read loops to spng, heif, giflib and ppm load [kleisauke]
+- block zero width or height images from imagemagick load [Koen1999]
+- check for overflow in gifload height [lovell]
+- fix msb_first default in ppm load and save [ewelot]
+- force binary mode on win for connection read / write [Alreiber]
+- better testing for output to target [barryspearce]
+- ppmload_source was missing is_a [ewelot]
+- improve webpload rounding and blending behaviour [lovell]
+- fix range clip in int32 -> unsigned casts [ewelot]
+- fix precision error in clip of float -> int casts [ewelot]
+- fix load of HEIC images with 0 length metadata [ddennedy-gpsw]
+- revise rounding in reduce [kleisauke]
+
+6/9/20 started 8.10.2
+- update magicksave/load profile handling [kelilevi]
+- better demand hint rules [kaas3000]
+- fix tiff thumbnail from buffer and source [vansante]
+- in jpegsave, don't set JFIF resolution if we set EXIF resolution
+- bump minimum libheif version to 1.3 [lovell]
+- dzsave in iiif mode could set info.json dimensions off by one [Linden6]
+- pdfload allows dpi and scale to both be set [le0daniel]
+- allow gaussblur sigma zero, meaning no blur
+- better heif signature detection [lovell]
+- fix vips_fractsurf() typo [kleisauke]
+- better heif EOF detection [lovell]
+- fix gir build with g-o-i 1.66+ [László]
+- improve seek behaviour on pipes
+- add "speed" param to heifsave [lovell]
+- fix regression in C path for dilate / erode [kleisauke]
+- fix build with libheif save but no load [estepnv]
+
+9/8/20 started 8.10.1
+- fix markdown -> xml conversion in doc generation
+- remove typedef redefinitions to please old gccs
+- fix regression in tiff pyramid thumbnailing [tand826]
+- stop 0-length buffer being passed to imagemagick [lovell]
+- convert no-profile CMYK to RGB on save [augustocdias]
+- ensure SVG loader skips input with chars outside x09-x7F range [lovell]
+- better mask sizing in gaussmat [johntrunc]
+- fix tiffsave "squash" handling [barryspearce]
+- fix jpegload autorotate [chregu]
+- only start the background render thread on first use
+
+24/1/20 started 8.10.0
+- more conformat IIIF output from dzsave [regisrob]
+- add @id to dzsave to set IIIF id property [regisrob]
+- add max and min to region shrink [rgluskin]
+- allow \ as an escape character in vips_break_token() [akemrir]
+- tiffsave has a "depth" param to set max pyr depth
+- libtiff LOGLUV images load and save as libvips XYZ
+- add gifload_source, csvload_source, csvsave_target, matrixload_source,
+ matrixsave_source, pdfload_source, heifload_source, heifsave_target,
+ ppmload_source, ppmsave_target
+- revise vipsthumbnail flags
+- add VIPS_LEAK env var
+- add vips_pipe_read_limit_set(), --vips-pipe-read-limit,
+ VIPS_PIPE_READ_LIMIT
+- revise gifload to fix BACKGROUND and PREVIOUS dispose [alon-ne]
+- add subsample_mode, deprecate no_subsample in jpegsave [Elad-Laufer]
+- add vips_isdirf()
+- add PAGENUMBER support to tiff write [jclavoie-jive]
+- add "all" mode to smartcrop
+- flood fill could stop half-way for some very complex shapes
+- better handling of unaligned reads in multipage tiffs [petoor]
+- mark old --delete option to vipsthumbnail as deprecated [UweOhse]
+- png save with a bad ICC profile just gives a warning
+- add "premultipled" option to vips_affine(), clarified vips_resize()
+ behaviour with alpha channels
+- improve bioformats support with read and write of tiff subifd pyramids
+- thumbnail exploits subifd pyramids
+- handle all EXIF orientation cases, deprecate
+ vips_autorot_get_angle() [Elad-Laufer]
+- load PNGs with libspng, if possible
+- deprecate heifload autorotate -- it's now always on
+- revised resize improves accuracy [kleisauke]
+- add --vips-config flag to show configuration info
+- add "bitdepth" param to tiff save, deprecate "squash" [MathemanFlo]
+- tiff load and save now supports 2 and 4 bit data [MathemanFlo]
+- pngsave @bitdepth parameter lets you write 1, 2 and 4 bit PNGs
+- ppmsave also uses "bitdepth" now, for consistency
+- reduce operation cache max to 100
+- rework the final bits of vips7 for vips8 [kleisauke]
+- --disable-deprecated now works [kleisauke]
+- vipsheader allows "stdin" as a filename
+- gifload allows gifs with images outside the canvas
+- wasm compatibility patches [kleisauke]
+- webpsave has a @profile param
+
+24/4/20 started 8.9.3
+- better iiif tile naming [IllyaMoskvin]
+
+31/1/19 started 8.9.2
+- fix a deadlock with --vips-leak [DarthSim]
+- better gifload behaviour for DISPOSAL_UNSPECIFIED [DarthSim]
+- ban ppm max_value < 0
+- add fuzz corpus to dist
+- detect read errors correctly in source_sniff
+- fix regression in autorot [malomalo]
+- thumbnail on HEIC images could select the thumbnail incorrectly under some
+ size modes [ZorinArsenij]
+
+20/6/19 started 8.9.1
+- don't use the new source loaders for new_from_file or new_from_buffer, it
+ will break the loader priority system
+- fix thumbnail autorot [janko]
+- fix a warning with magicksave with no delay array [chregu]
+- fix a race in tiled tiff load [kleisauke]
+- better imagemagick init [LebronCurry]
+- lock for metadata changes [jcupitt]
+
+20/6/19 started 8.9.0
+- add vips_image_get/set_array_int()
+- disable webp alpha output if all frame fill the canvas and are solid
+- support arrays of delays for animated images [deftomat]
+- add "unlimited" flag to svgload
+- disable webp alpha output if all frames fill the canvas and are solid
+- add "compression" option to heifsave [lovell]
+- support webp and zstd compression in tiff
+- loaders use "minimise" to close input files earlier
+- integrate support for oss-fuzz [omira-sch]
+- add vips_switch() / vips_case() ... fast many-way ifthenelse
+- better const handling for arithmetic operators fixes comparisons against out
+ of range values
+- sharpen restores input colourspace
+- handle alpha in heifload / heifsave [meyermarcel]
+- add @interpretation and @format to rawload
+- nifti load/save uses double for all floating point metadata
+- add vips_error_buffer_copy()
+- add VipsSource and VipsTarget: a universal IO class for loaders and savers
+- jpeg, png, tiff (though not tiffsave), rad, svg, ppm and webp use the
+ new IO class
+- rewritten ppm load/save is faster and uses less memory
+- add @no_strip option to dzsave [kalozka1]
+- add iiif layout to dzsave
+- fix use of resolution-unit metadata on tiff save [kayarre]
+- support TIFF CIELAB images with alpha [angelmixu]
+- support TIFF with premultiplied alpha in any band
+- block metadata changes on shared images [pvdz]
+- RGB and sRGB are synonmous
+
+17/9/19 started 8.8.4
+- improve compatibility with older imagemagick versions
+- remove realpath, since it can fail on systems with grsec
+
+31/8/19 started 8.8.3
+- revert sharpen restoring the input colourspace
+- xres/yres tiffsave params were in pixels/cm [f--f]
+
+9/7/19 started 8.8.2
+- better early shutdown in readers
+- don't attempt to save large XMP to jpeg [tnextday]
+- always fetch HEIC metadata from the main image [zhoux2016]
+- fix loop in malformed ppm [Kyle-Kyle]
+- better support for PNGs with long comment names
+- fix build with GM
+- add locks for pdfium load
+- fix build with MSVC
+- fix a problem with shinkv tail processing [angelmixu]
+- fix a read one byte beyond buffer bug in jpegload
+- make GIF parsing less strict
+- better feof() handling in GIF load
+- clip coding and interpretation on vips image read
+- check image bounds for GIF load
+- prevent over-pre-shrink in thumbnail [kleisauke]
+- fix sharpen with sigma 0.5 [2h4dl]
+- sharpen restores input colourspace
+- verify bands/format for coded images
+- improve data_length handling for jpeg metadata
+
+24/5/19 started 8.8.1
+- improve realpath() use on older libc
+- better magickload error messages
+- more consistent behaviour for page-height metadata
+- fix for composite with many small images and some combinations of blend modes
+- fix memleak in tiff pyr save to memory [scossu]
+- istiff attempts to read the first directory rather than just testing the
+ magic number [przemyslawpluta]
+- much faster ismagick() [jcupitt]
+- better behaviour for vips_region_fetch() if request lies partly ouside image
+- remove 256 band limit in arithmetic.c [erdmann]
+- disable Orc if building with CET [lovell]
+- fix vipsthumbnail with pyr tiff [kleisauke]
+- text autofit could occasionally terminate early [levmorozov]
+- fewer warnings on tiffload [chregu]
+- vips_resize() breaks aspect ratio and limits shrink to prevent <1px
+ dimensions [lovell]
+
+21/9/18 started 8.8.0
+- much faster smartcrop [lovell]
+- add low/high to smartcrop [jcupitt]
+- add XMP support to png read/write [jcupitt]
+- deprecate thumbnail auto_rotate, add no_rotate [jcupitt]
+- implement thumbnail shrink-on-load for openslide images [jcupitt]
+- add animated webp support [jcupitt]
+- revise vips_cast() to improve behaviour with uint images [erdmann]
+- add bandand()/or()/eor() to cplusplus binding [clcaalu]
+- implement shrink-on-load for tiff pyramids [jcupitt]
+- added vips_image_set_blob_copy() [jcupitt]
+- don't stop composite on first non-transparent image [felixbuenemann, GDmac]
+- add vips_rect_overlapsrect()
+- composite is much faster at positioning subimages
+- stop tiff pyr layers if width or height drop to 1 [gvincke]
+- dzsave has a new skip_blanks option
+- add vips_CMYK2XYZ() and vips_XYZ2CMYK(), plus associated routes
+- include cmyk and srgb fallback profiles
+- add vips_profile_load() and use it everywhere
+- fix race in temp filename creation [lhecker]
+- add @reduction_effort param to webpsave [lovell]
+- add @option_string param to thumbnail_buffer [kleisauke]
+- add XMP, IPCT, ICC, EXIF etc. support to magickload/magicksave
+- much lower memuse for gifload
+- tilecache speedups
+- add vips_heifload(), vips_heifsave()
+- add heif thumbnail support to vips_thumbnail()
+- free threadpool earlier, reducing mem growth for some long-running
+ processes [jtorresfabra]
+- add vips_region_fetch() / _width() / _height() for language bindings
+- vips_text() supports justification
+- move vips_image_set_kill() and iskilled() to the public API
+- dzsave to szi sets suffix correctly [martinweihrauch]
+- dzsave szi writes "scan-properties.xml"
+- add vips_image_(get|set)_image()
+- add openslideload option to attach all associated images as metadata
+- dzsave to szi will write all associated images
+- remove old c++ and python interfaces
+- vipsthumbnail can thumbnail animated and multipage images
+- deprecate webpload @shrink, use @scale instead
+
+31/3/19 started 8.7.5
+- better buffer sizing in tiff reader [omira-sch]
+
+4/1/19 started 8.7.4
+- magickload with magick6 API did not chain exceptions correctly causing a
+ memory leak under some conditions [kleisauke]
+- zero memory on allocate to prevent write of uninitialized memory under some
+ error conditions [Balint Varga-Perke]
+
+21/11/18 started 8.7.3
+- fix infinite loop for autofit with non-scaleable font
+- mapim was not offsetting by window offset [erdmann]
+- better rounding for scale [kleisauke]
+- fix a memleak in magick6load [kleisauke]
+
+21/11/18 started 8.7.2
+- more info output for temp files to help diagnose problems
+- vips_text() could set the wrong DPI
+- vips_text() leaked in autofit mode
+
+23/9/18 started 8.7.1
+- update function list in docs [janko-m]
+- test for g_str_to_ascii() [jcupitt]
+- fix temp file open on Windows and fallback on linux [lovell]
+
+23/12/17 started 8.7.0
+- add magicksave, save image with libMagick [dlemstra]
+- remove jpeg thumbnail from EXIF if "jpeg-thumbnail-data" has been removed by
+ user
+- hough_line scales width to 0 - 180, not 0 - 360
+- hough_line is 4x faster
+- hough_circle is 2x faster
+- add vips_sobel() and vips_canny() edge detectors
+- add vips_rotate() ... a convenience method for vips_similarity()
+- svgload was missing is_a [lovell]
+- better header sniffing for small files
+- drop incompatible ICC profiles before save
+- better hasalpha rules
+- create funcs always make MULTIBAND (ie. no alpha)
+- use O_TMPFILE, if available [Alexander--]
+- set "interlaced=1" for interlaced JPG and PNG images
+- add PDFium PDF loader
+- jpegload adds a jpeg-chroma-subsample field with eg. 4:4:4 for no
+ chrominance subsampling.
+- tiffload, pdfload, magickload set VIPS_META_N_PAGES "n-pages" metadata item
+- add fontfile option to vips_text() [fangqiao]
+- add vips_transpose3d() -- swap major dimensions in a volumetric image
+- remove vips7 stuff from default API ... you must now #include it explicitly
+- added vips_argument_get_id() to fix derived classes on win32 [angelmixu]
+- fix compile with MSVC 2017 [angelmixu]
+- pdfload has a option for background
+- vips7 C++ interface defaults off
+- make members, getters and operators "const" in cpp API
+- composite has params for x/y position of sub-images [medakk]
+- add Mitchell kernel
+- pyramid builders have a choice of 2x2 shrinkers [harukizaemon]
+- add `palette` option to pngsave [felixbuenemann]
+- add basic nifti load/save support
+- support writing string-valued fields via libexif
+- paste in the test suite from pyvips
+- get EXIF tag names from tag plus ifd [@Nan619]
+- escape ASCII control characters in XML
+- magickload now sniffs some file types itself
+- update radiance load from upstream
+- add region_shrink to tiffsave
+- mapim could fail for float index images with coordinates out of int range
+- scale openexr alpha to 0 - 255
+- close input earlier, when we can [kleisauke]
+- add vips_object_get_args() for language bindings [kleisauke]
+
+12/3/18 started 8.6.4
+- better fitting of fonts with overhanging edges [Adrià]
+- revise C++ example [fangqiao]
+- strict round down on jpeg shrink on load [davidwood]
+- configure test for g++ 7.2 and composite.cpp
+- don't Ping in magickload, too unreliable
+- ensure WebP can add metadata when compiled with libwebpmux [lovell]
+- improve accuracy of vector path convolution [felixbuenemann]
+
+12/2/18 started 8.6.3
+- use pkg-config to find libjpeg, if we can
+- better clean of output image in vips_image_write() fixes a crash
+ writing twice to memory
+- better rounding behaviour in convolution means we hit the vector path more
+ often
+- fix a crash if a delayed load failed [gsharpsh00ter]
+- icc_import attaches the fallback profile if it used it
+
+5/1/18 started 8.6.2
+- vips_sink_screen() keeps a ref to the input image ... stops a rare race
+- fix a minor accidental ABI break in 8.6.0 -> 8.6.1 [remicollet]
+- fix read of plane-separate TIFFs with large strips [remicollet]
+- fix a C++ warning in composite.cpp [lovell]
+- remove number of images limit in composite
+- composite allows 1 mode ... reused for all joins
+- fix race in vips_sink() for seq read
+
+10/12/17 started 8.6.1
+- fix mmap window new/free cycling
+- fix some compiler warnings
+- remove the 64-image limit on bandary operations
+- better version date [bmwiedemann]
+- bump wrapper script version [bgilbert]
+- fix a memleak on error during jpeg buffer write [lovell]
+- fix misspelling of IPTC as IPCT [lovell]
+- seq could be set on small images opened in random-access mode [aferrero2707]
+- fix small memleak in dzsave [lovell]
+- small speedup for rgb->g [lovell]
+
+15/4/17 started 8.6.0
+- supports fits images with leading non-image HDUs, thanks benepo
+- add vips_image_new_from_image() and vips_image_new_from_image1() ... make a
+ constant image
+- add new_from_image() to Python as well
+- slight change to cpp new_from_image() to match py/C behaviour
+- vips_conv(), vips_compass(), vips_convsep() default to FLOAT precision
+- add FORCE resize mode to break aspect ratio
+- add vips_thumbnail_image()
+- better prefix guessing on Windows, thanks tumagonx
+- savers support a "page_height" option for multipage save
+- rename 'disc' as 'memory' and default off
+- add vips_find_trim(), search for non-background areas
+- remove lcms1 support, it had bitrotted
+- `join` tagged as seq
+- support tiffsave_buffer for pyramids, thanks bubba
+- thumbnail and vipsthumbnail have an option for rendering intent, thanks
+ kleisauke
+- set file create time on Windows, thanks dlong500
+- remove python tests ... moved to pyvips test suite
+- vips7 and vips8 python bindings default to off ... use the new pyvips
+ binding instead
+- better svgload: larger output, handle missing width/height, thanks lovell
+- add vips_gravity() ... embed, but with direction rather than position
+- vips_text() can autofit text to a box, thanks gargsms
+- add vips_composite() / vips_composite2(): merge a set of images with
+ a set of blend modes
+- better gobject-introspection annotations, thanks astavale
+- vips_image_write() severs all links between images, when it can ... thanks
+ Warren and Nakilon
+- vector path for convolution is more accurate and can handle larger masks
+- linear and cubic kernels for reduce are higher quality
+- added vips_value_set_blob_free()
+- "--size Nx" to vipsthumbnail was broken, thanks jrochkind
+- fix build with gcc 7
+- add vips_fill_nearest() ... fill pixels with nearest colour
+- add VIPS_COMBINE_MIN, a new combining mode for vips_compass()
+- vips_hist_find_indexed() now has a @combine parameter
+- vips_affine() and vips_similarity() have a "background" parameter
+- fix nasty jaggies on the edges of affine output, thanks chregu
+- add gif-delay, gif-comment and gif-loop metadata
+- add dispose handling to gifload
+- dzsave outputs extra right and bottom overlap-only tiles, for closer spec
+ adherence
+- deprecate the "centre" option for vips_resize(): it's now always on
+- setting the EXIF data block automatically sets other image tags
+- add "extend" option to affine; resize uses it to stop black edges
+
+29/8/17 started 8.5.9
+- make --fail stop jpeg read on any libjpeg warning, thanks @mceachen
+- don't build enumtypes so often, removing perl as a compile dependency
+- fix a crash with heavy use of draw operations from language bindings,
+ thanks @Nakilon
+
+2/8/17 started 8.5.8
+- fix transparency detection in merge, thanks Haida
+- define env var VIPS_WARNING to hide warning messages
+- shut down dzsave output earlier to help mark-sweep bindings
+- fix webp thumbnail upscale, thanks Kleis
+
+9/6/17 started 8.5.7
+- better smartcrop
+- transform cmyk->rgb automatically on write if there's an embedded profile
+ and the saver does not support cmyk
+- fix DPI mixup in svgload ... we were writing images about 20% too large,
+ thanks Fosk
+
+19/5/17 started 8.5.6
+- tiff read with start page > 0 could break edge tiles or strips
+- raise b64 limit to allow for huge profiles (thanks jaume)
+- fix error return in blob save (thanks jaume)
+- tag vipsprofile as py2 (thanks ioquatix)
+- don't cache thumbnail (thanks tomasc)
+
+23/4/17 started 8.5.5
+- doc polishing
+- more improvements for truncated PNG files, thanks juyunsang
+- improve corrupted jpg handling, thanks juyunsang
+- fix small test suite issues on os x
+
+23/4/17 started 8.5.4
+- don't depend on image width when setting n_lines, thanks kleisauke
+
+7/4/17 started 8.5.3
+- more link fixing in docs
+- revise cache sizing again to help out of order errors under heavy load, thanks
+ kleisauke
+
+25/3/17 started 8.5.2
+- better behaviour for truncated PNG files, thanks Yury
+- missing proto for vips_tiffsave_buffer(), thanks greut
+- move some docs from the wiki and blog into core libvips docs
+- add support for markdown in docs
+
+25/3/17 started 8.5.1
+- init more classes earlier, thanks David
+
+13/10/16 started 8.5.0
+- rewritten buffer system is safer and frees memory earlier
+- added tiff save to buffer
+- added dzsave save to buffer (zip only)
+- revise header get/set functions
+- better vipsheader behaviour with complex field types
+- added vips_image_hasalpha()
+- added vips_thumbnail() / vips_thumbnail_buffer()
+- webpload/webpsave read and write icc, xmp, exif metadata
+- better >4gb detect for zip dzsave output [Felix Bünemann]
+- all loaders have a @fail option, meaning fail on first warning, though it
+ only does anything for jpg and csv
+- add vips_image_get_fields() to help bindings
+- add tiff multi-page read/write
+- add VIPS_META_PAGE_HEIGHT metadata
+- IM6/IM7 magickload supports page/n/page-height, all_frames deprecated
+- gifload supports n/page-height
+- added #defines for VIPS_SONAME, VIPS_LIBRARY_CURRENT, VIPS_LIBRARY_REVISION,
+ VIPS_LIBRARY_AGE
+- better support for bscale / bzero in fits images
+- deprecate vips_warn() / vips_info(); use g_warning() / g_info() instead
+- vipsthumbnail supports much fancier geometry strings, thanks tomasc
+- vips_thumbnail() has new @size option
+- fix --vips-cache-max etc.
+- add compute reordering, plus some new API to support it:
+ vips_reorder_margin_hint() and vips_reorder_prepare_many(), thanks
+ aferrero2707
+- kick load operations from cache on read error, thanks gaillard
+- fix return from C++ assignment operator overloads (+=, -= etc)
+- add @max_slope to vips_hist_local() to implement CLAHE, thanks hunter-87
+- vips_gaussnoise() pixels are reproducible on recalc, thanks MvGulik
+- max/min sort values by y and x coordinate
+- tiff read uses libtiff scanline API if rows-per-strip is large
+- vips_region_shrink() knows about alpha, helps dzsave and tiffsave
+- use expat, not libxml, for XML load ... removes a required dependency, since
+ we get expat as part of glib
+- new sequential mode infrastructure is faster and more flexible
+- add vips_smartcrop(), based on sharp's smartcropper
+- vipsthumbnail has a --smartcrop option
+- added vips_rot90() etc. convenience functions
+- fix vips_resize() bug when hscale and vscale were very different
+
+8/12/16 started 8.4.5
+- allow libgsf-1.14.26 to help centos, thanks tdiprima
+
+11/11/16 started 8.4.4
+- fix crash in vips.exe arg parsing on Windows, thanks Yury
+
+18/10/16 started 8.4.3
+- fix error detection in gif_close, thanks aaron42net
+- fix tiny threading memleak
+- improve compatibility with very old glib, see #548
+
+27/9/16 started 8.4.2
+- small doc improvements
+- fix error message for metadata fetch type mismatch
+- resolve a race condition in thread shutdown, thanks Lovell
+
+1/5/16 started 8.4
+- many more wepsave options [Felix Bünemann]
+- added quant_table option to wepsave [Felix Bünemann]
+- added @n option to pdfload, thanks andris
+- dzsave won't write empty tiles in google mode, thanks bverem, perog,
+ felixbuenemann
+- allow nested [] in CLI args
+- restore BandFmt on unpremultiply in vipsthumbnail
+- better python detection and build [Felix Bünemann]
+- max-alpha defaults to 65535 for RGB16/GREY16
+- added radsave_buffer [Henri Chain]
+- support tiff orientation tag
+- autorotate option for tiff load
+- tiffsave converts for jpg if jpg compression is turned on
+- tiffsave supports --strip
+- conversions to GREY16 could lock
+- free pixel buffers on image close as well as thread exit ... stops main
+ thread buffers clogging up the system
+- dzsave can write compressed zips [Felix Bünemann]
+- vips_image_write() only refs the input when it has to ... makes it easier to
+ combine many images in bounded memory
+- VImage::write() implementation was missing
+- VImage::write() return value changed from void to VImage to help chaining
+- added C++ arithmetic assignment overloads, += etc.
+- VImage::ifthenelse() with double args was missing =0 on options
+- better accuracy for reducev with smarter multiplication
+- better quality for vips_resize() with linear/cubic kernels
+- pyvips8 can create new metadata
+- better upsizing with vips_resize()
+- add imagemagick v7 support, thanks sachinwalia2k8
+- added vips_worley(), vips_perlin() noise generators
+- added vips_convf(), vips_convi(), vips_convasep(), vips_conva() ...
+ im_conv*() functions rewritten as classes
+- vips_convsep() calls vips_convasep() for the approximate case
+- new fixed-point vector path for convi is up to about 2x faster
+- gif loader can make 1, 2, 3, or 4 bands depending on file contents
+- support --strip for pngsave
+- add svgz support [Felix Bünemann]
+- rename boostrap.sh -> autogen.sh to help snapcraft
+- support unicode filenames on Windows
+- added VIPS_ROUND as well as VIPS_RINT
+- resize/reduce*/shrink*/affine now round output size to nearest rather than
+ rounding down, thanks ioquatix
+- better support for tile overlaps in google maps mode in dzsave
+- dzsave puts vips-properties.xml in the main dir for gm and zoomify layouts
+- resize and reduce have @centre option for centre convention downsampling
+- vipsthumbnail uses centre convention to better match imagemagick
+_ add vips_foreign_get_suffixes()
+
+19/8/16 started 8.3.4
+- better transparency handling in gifload, thanks diegocsandrim
+
+30/7/16 started 8.3.3
+- fix performance regression in 8.3.2, thanks Lovell
+- yet more robust vips file reading
+
+18/5/16 started 8.3.2
+- more robust vips image reading
+- more robust tiff read [Matt Richards]
+
+15/4/16 started 8.3.1
+- rename vips wrapper script, it was still vips-8.2, thanks Benjamin
+- export C++ operator overloads for MSVC linking [Lovell]
+- fix magickload @page with GraphicsMagick
+- add giflib5 support
+- allow resize >1 on one axis, <1 on the other
+- vips_resize has an optional @kernel argument
+- fix giflib4 detection [felixbuenemann]
+
+29/1/16 started 8.3
+- add vips_reduce*() ... a fast path for affine downsize
+- vips_resize() uses vips_reduce() with lanczos3
+- bicubic is better on 32-bit int images
+- add pdfload, svgload, gifload for PDF, SVG and GIF rendering
+- vipsthumbnail knows about pdfload and svgload
+- added @page param to magickload
+- matload is more specific (thanks bithive)
+- lower mem use for progressive jpg decode
+- sharpen has a new @sigma param, @radius is deprecated
+- sharpen allows a much greater range of parameters
+- sharpen defaults now suitable for screen output
+- better handling of deprecated args in python
+- much better handling of arrayimage command-line args
+- faster hist_find (Lovell Fuller)
+- webpload has a @shrink parameter for shrink-on-load
+- vipsthumbnail knows about webp shrink-on-load
+- better behaviour for vips_cast() shift of non-int types (thanks apacheark)
+- python .bandrank() now works like .bandjoin()
+- vipsthumbnail --interpolator and --sharpen switches are deprecated
+- switches to disable PPM, Rad and Analyze support
+- added VIPS_COUNT_PIXELS(), overcomputation tracking
+- @out_format in vips_system() can contain [options]
+- webpsave_buffer no longer ignores @lossless, thanks aaron42net
+- float tiff tagged as scRGB to match photoshop convention, thanks Murat
+- better jpeg autorot, thanks otto
+
+24/3/16 started 8.2.4
+- fix nohalo and vsqbs interpolators, thanks Rafael
+
+27/1/16 started 8.2.3
+- fix a crash with SPARC byte-order labq vips images
+- fix parsing of filenames containing brackets, thanks shilpi230
+- fix hist_entropy (lovell)
+- small fixes to radiance load
+
+12/1/16 started 8.2.2
+- changes to ease compiling C++ binding with MSVC [Lovell Fuller]
+- reorder file tests to put slow loaders last
+- ifthenelse needs less C stack during eval
+- better rounding in bilinear interpolator
+- fix to "make check" in non-C locales [felixbuenemann]
+- use compiler builtins isnan, isinf, fabs, fmin, fmax, ceil, floor when
+ possible [Lovell Fuller]
+- tune vips_shrinkh(), 30% faster [Lovell Fuller]
+- remove SEQ hint from vips_subsample(), fixes cli performance [erdmann]
+- fix double free on attach ICC profile from file in tiff write [erdmann]
+- use g_assert_not_reached()
+- better vips-from-C docs
+- remove Duff from im_conv() / im_conv_f() for a 25% speedup [Lovell Fuller]
+
+1/1/16 started 8.2.1
+- add a compat stub [Benjamin Gilbert]
+- python bandjoin is now just an instance function
+- small doc improvements
+- small vips7 C++ improvement
+- remove exception specifications from vips8 C++ interface [Lovell Fuller]
+- VImage::get_typeof() now returns GType
+
+7/10/15 started 8.2.0
+- added im_bufmagick2vips(), a vips7 wrapper for magick load from buffer
+- fetch unset property now returns default value rather than warning
+- many more const declarations to help gobject-introspection
+- rewritten vips_shrink() is 2x faster, much lower memuse, now handles complex
+- only allow [] for filename options
+- add memory.h to Python API .. makes tracked highwater visible
+- added bandjoin_const to add constant bands to an image
+- better alpha handling for tiff write, thanks sadaqatullahn
+- better cache sizing for vips_resize()
+- sizealike / formatalike / bandsalike elide completely if they can for
+ a x2 saving in C stack use in many cases
+- added vips_mapim() ... resample with an index image, plus test
+- try to improve vips_resize() quality a little more
+- vips_resize() can do non-square resizes
+- dzsave removes tile metadata by default, thanks Benjamin
+- jpeg strip option removes a little more, thanks Benjamin
+- added vips_image_new_from_memory_copy()
+- improve vips_sink_screen() stability under heavy load
+- added vips_arrayjoin()
+- Python x.bandjoin(y) is now x.ibandjoin(y), sorry
+- faster and lower-mem TIFF read
+- faster bilinear interpolator
+- TIFF loads and saves IMAGEDESCRIPTION
+- add --properties flag to tiffsave
+- dzsave defaults changed: now writes 256x256 jpegs for non-edge tiles, thanks
+ Daniel
+
+7/5/15 started 8.1.1
+- oop, vips-8.0 wrapper script should be vips-8.1, thanks Danilo
+- fix vips7 pathname parsing on windows, thanks Lovell
+
+7/5/15 starteld 8.1.0
+- add vips_premultiply(), vips_unpremultiply()
+- change the alpha range rules for vips_flatten() to match vips_premultiply()
+- vipsthumbnail uses vips_resize() rather than its own code
+- vipsthumbnail uses vips_premultiply() for better alpha quality
+- added bandand() bandor() bandeor() convenience funcs to Python
+- oops, base64 encode could pad by up to two zero bytes
+- added VipsRefString as a thing that gi bindings can unpack
+- support "with Vips.Image as i:" in Python
+- try to support DOS CSV and PPM files on linux
+- add vips_byteswap(), remove byteswap option from vips_copy()
+- add vips_bandfold()/vips_bandunfold()
+- dzsave supports zip output > 4gb, thanks benjamin
+- add support for HSV colourspace [Jonas Øgaard]
+- skip oversized markers in jpeg write
+- jpeg exif tags saved as name rather than title
+- can now set any jpeg exif tag, not just modify existing tags
+- add vips_hist_entropy()
+- vips_log(), vips_log10() are zero-avoiding
+- better overlap handling for dzsave, thanks robclouth
+- add @spacing option to vips_text()
+- tiff loads and saves IPCT and Photoshop data
+
+7/5/15 started 8.0.3
+- dzsave and tif pyr write could fail for some image dimensions, thanks Jonas
+
+4/5/15 started 8.0.2
+- fix a refcount error in C++ wrapper, thanks huskier
+- better C++ api test
+- test suite improvements
+- remove a couple of stray header decls, thanks benjamin
+
+25/4/15 started 8.0.1
+- fix some compiler warnings
+- work around a glib bug that can cause segv under load
+- add some notes on threading to the docs
+- better leak reporting
+
+11/2/15 started 8.0
+- remove old doc stuff, lots of doc improvements
+- add fliphor(), flipver(), rot90(), rot180(), rot270(), median(), dilate(),
+ erode() convenience methods to Python and C++
+- python: use [] to index and slice image bands, use () to get a point
+- c++: use [] to band index, () returns a vector
+- add shift option to cast
+- sRGB2scRGB and scRGB2sRGB scale 16-bit alpha to and from 8-bit
+- add magickload_buffer() [mcuelenaere]
+- add vips_foreign_is_a_buffer() [mcuelenaere]
+- added test_foreign.py, plus more test images
+- added vips_region_shrink(), fast x2 shrinker
+- rewritten tiff writer is about 3 - 4x faster at making pyramids
+- jpg, magick, png, tiff readers now use only 1 fd per input image
+- added vips_info_set(), vips_progress_set(), vips_profile_set() ... bindings
+ can now support all the vips command-line options if they wish
+- better conversion to greyscale, thanks bkw
+- add vips_image_copy_memory(), improves stability with heavy threading
+- jpegsave supports new mozjpeg features [lovell]
+- add vips_vipsload(), vips_vipssave() ... why not
+
+26/3/15 started 7.42.4
+- im_maxpos_avg() avoids NaN
+- small tiffsave doc improvements
+- better thresholding for tiffsave "squash" mode
+- add @miniswhite mode to tiffsave
+
+6/2/15 started 7.42.3
+- bump version for back-compat ABI change
+- added vips_image_memory(), an alias for vips_image_new_memory()
+- improvements to configure for python
+- remove --disable-cxx configure flag
+- python imageize preserves interpretation
+- fix dzsave as a target format
+
+30/12/14 started 7.42.2
+- C++ required output params were broken, thanks Lovell
+- remove VImage::scale() to get scale from header, it clashed with the
+ VipsScale operator, thanks Lovell
+- allow c++ set enum from string
+- display param default and range in usage
+- better docs
+- more tests
+- renamed VIPS_FOREIGN_DZ_DEPTH_1 as VIPS_FOREIGN_DZ_DEPTH_ONE etc. to help
+ bindings
+- vipsthumbnail will return an error code if one or more conversions failed
+- disable chroma subsample in jpeg-tiff if Q >= 90
+- try to handle tiffs with old-style 8-bit colormaps
+- rename vipsthumbnail -o as -f, -o stays as a hidden flag
+- fix some small leaks
+- faster openslide load, thanks Benjamin
+- add VInterpolate class to cplusplus binding, thanks Lovell
+- add lower-level operation cache access
+- turn on leak testing in test suite
+- don't use isnormal() to test for crazy FP numbers, thanks Murat
+- much faster RGB16 -> sRGB path
+
+24/12/14 started 7.42.1
+- add gobject-2.0 to Requires: in vips and vips-cpp .pc files
+- bump soname
+- fix VipsBlob read
+- remove "future" dependency, thanks bgilbert
+
+4/11/14 started 7.42.0
+- better default resolution for png load
+- better pbm (one bit) load, better pfm (float) load/save
+- added pbm (one bit) save
+- changed vips_gaussblur() parameters, sorry
+- add .szi as a dzsave zip synonym
+- support tiff XMP metadata
+- support @density arg to magickload [Lovell]
+- support python3.4 and python2.7 in new python binding
+- vips_gaussmat() and vips_logmat() are now int by default, to match
+ vips_conv(), and use @precision, not @integer
+- added --disable-pyvips8 switch to turn off new py binding
+- "vips thing" exit status can now be used to test for optional components
+
+25/7/14 started 7.41.0
+- start working on --disable-deprecated
+- fix pngload with libpng >1.6.1
+- add vips_resize()
+- return of vips_init(), but just for bindings
+- revised type.c to make it more binding-friendly
+- add @background arg to save: the colour to flatten against
+- add VIPS_ARGUMENT_MODIFY flag ... used for draw_circle etc, meaning an op
+ which modifies its argument
+- rename VIPS_OPERATION_RELATIONAL_NOTEQUAL as VIPS_OPERATION_RELATIONAL_NOTEQ
+ for consistency
+- python vips8 binding
+- python vips8 test suite: test_arithmetic.py, test_colour.py,
+ test_conversion.py
+- move zoomify ImageProperties file, now a better match to the offical tool
+- rename VIPS_ANGLE_180 as VIPS_ANGLE_D180 etc. to help python
+- remove cimg support, we have a gmic plugin now instead
+- add support for vips8 plugins
+- added "autorotate" option to jpeg load
+- added autorot operator
+- added @filter option to pngsave (Lovell)
+- C++ vips8 binding
+
+27/10/14 started 7.40.12
+- better tiff detection (Lovell)
+- fix memleak in sharpen (Lovell)
+- fix profile handling in XYZ2scRGB, thanks Lovell
+
+8/10/14 started 7.40.11
+- rework extra band handling for colour functions
+- set interpretation of matlut output more carefully
+
+8/9/14 started 7.40.10
+- icc_import and icc_transform checks the input profile for compatibility
+ with the image, thanks James
+- try to make vips_thread_shutdown() optional
+
+8/9/14 started 7.40.9
+- support jfif resunit "none"
+- support GRAY as an input and output ICC space
+- fix a read loop with setjmp() in png read, if the png file is broken
+- fix vipsthumbnail with both input cmyk and output rgb profiles specified
+- vipsthumbnail retries with specified input profile if embedded profile is
+ broken
+- add @profile option to pngsave, matching tiff and jpeg
+- fix a race in the operation cache [Lovell]
+
+8/9/14 started 7.40.8
+- fix configure on rhel6 [Lovell]
+- mono <-> rgb converters were not handling extra bands, thanks James
+- support jpeg resunit "none"
+
+21/8/14 started 7.40.7
+- width and height were swapped in matlab load
+- set interpretation more carefully on matlab load
+- fix memleak in tilecache [Lovell]
+- fix memleak in VipsArray [Lovell]
+- fix memleak in webp load from buffer [Lovell]
+- fix memleak in png save to buffer [Lovell]
+- make out of order read in png and jpg a fatal error
+- add thread_shutdown() to C++ (and thereby to python)
+
+12/8/14 started 7.40.6
+- more doc fixes
+- fix similarity rotate+scale, thanks Topochicho
+- fix 16-bit PNG save, thanks John
+- fix dzsave date on Windows, thanks John
+- fix vipsthumbnail on many-core systems, thanks James
+
+25/7/14 started 7.40.5
+- fix a race in im_maxpos_avg()
+- limit n_thr on tiny images
+- don't exit() on memleak detected, just warn
+- add "autocrop" option to openslide load
+- argh fix affine, again, there were sometimes black bars with nohalo and the
+ vips8 interface
+- pngsave in interlaced mode makes a copy of the image, so it's always seq
+- vipsthumbnail shrinks to 1/2 window_size
+- vipsthumbnail has an anti-alias filter between shrink and affine
+- vipsthumbnail defaults to bicubic
+- better rounding behaviour for fixed-point bicubic reduces noise
+- fix pngload with libpng >=1.6.11
+- fix colour for openslide read associated
+
+4/7/14 started 7.40.4
+- fix vips_rawsave_fd(), thanks aferrero2707
+- fix im_point()
+- vips_scale() now does round to nearest to avoid rounding errors
+- improve im_openout() compat macro
+- more vips7 compatibility fixes, thanks steve
+- more robust vips_system()
+- add webp support to vips7
+
+30/6/14 started 7.40.3
+- fix interlaced thumbnails in vipsthumbnail, thanks lovell
+- fix use of "header" in benchmark/, thanks David
+- fits save now caches the image before write, so it's top-to-bottom
+- add --properties argument to dzsave, thanks bgilbert, jhenriksen
+
+25/6/14 started 7.40.2
+- dzsave write to zip stops at 4gb, thanks bgilbert
+- improve short option name handling, thanks bgilbert
+- added --enable-docs configure option to help freebsd
+- removed a bash-ism from configure to help freebsd
+- don't assume GType fits in an int to help freebsd
+
+24/6/14 started 7.40.1
+- revise man.1 pages
+- fix vips_guess_prefix()
+
+23/6/14 started 7.40.0
+- version bump
+- renamed "header" as "vipsheader" and "edvips" as "vipsedit"
+
+21/1/14 started 7.39.0
+- auto-decode for (almost) all operations, see vips_image_decode()
+- background render thread cleans up and quits neatly
+- colourspace has a source_space option
+- operations can be tagged as "deprecated"
+- redo im_draw_circle(), im_draw_flood(), im_draw_line(), im_draw_mask(),
+ im_draw_image(), im_draw_rect(), im_draw_point(), im_read_point(),
+ im_draw_smudge(), im_label_regions() as classes
+- better rounding in vips_flatten()
+- VipsStatistic operations are sequential
+- vipsthumbnail has --rotate auto-rotate option
+- removed embedded thumbnail reader from vipsthumbnail: embedded thumbnails
+ are too unlike the main image
+- fix to vipsthumbnail --crop, thanks Alessandro
+- add vips_sum()
+- add vips_hough base class and vips_hough_line()
+- add "mode" param to vips_draw_image()
+- add vips_hough_circle()
+- reduce default cache size to 1,000 operations
+- added "postbuild" signal
+- vips_system() now supports many input images and you can change image
+ argument order
+- support 16-bit palette TIFFs, plus palette TIFFs can have an alpha
+- libgsf-1 is now an optional dependency
+- dzsave can directly write a ZIP file
+- add ".vips" as an alternative suffix for vips files
+- added vips_tiffload_buffer()
+- added vips_image_new_from_buffer(), vips_image_write_to_buffer()
+- added vips_object_set_from_string()
+- added @container option to dzsave
+- support 1/2/4 bit palette tiff images with alpha
+- vips_system() now uses g_spawn_command_line_sync()
+- added im_tile_cache_random() to help nip2
+- added hough_circle() to vips7 C++ API
+- added Travis CI config, thanks Lovell
+- im_*merge(), im_*mosaic(), im_match*(), im_global_balance*(), im_remosaic(),
+ im_*mosaic1(), im_*merge1() redone as classes
+- better filename tracking for globalbalance
+- revised vips8 image load/save API, now simpler and more logical
+- operations emit "invalidate" if any of their input images invalidate
+- operation cache drops ops on invalidate
+- skipahead is back, thanks to a new threadpool tweak
+
+6/3/14 started 7.38.6
+- grey ramp minimum was wrong
+- vipsthumbnail --crop could fail for very non-square images, thanks
+ Alessandro
+- fix a crash in vips_rawsave(), thanks Andrea
+- updated German translation, thanks Chris
+- fix coordinate error in affine, thanks ferryfax
+
+24/2/14 started 7.38.5
+- jpeg load from buffer could write to input, thanks Lovell
+- fix webpload from buffer, thanks Lovell
+- vips_sequential() could fail under heavy load
+- remove support for seq mode read for operations like extract
+
+13/2/14 started 7.38.4
+- --sharpen=none option to vipsthumbnail was broken, thanks ferryfax
+- more locking on property create and lookup to help very-threaded systems,
+ thanks Nick
+
+22/1/14 started 7.38.3
+- undeprecate VIPS_MASK_IDEAL_HIGHPASS and friends, ruby-vips was using them,
+ thanks ahacking
+
+22/1/14 started 7.38.2
+- auto RAD decode for affine
+- falsecolour was not working for some image types
+- foreign memory buffer images did not have the right dhint, broke
+ command-line falsecolour on sequential images
+- support many Radiance readers active at once
+- add secret "rgbjpeg" flag to vips_tiffsave() to help IIP
+
+19/1/14 started 7.38.1
+- bump soname, thanks benjamin
+- better conversion to and from scrgb/xyz for rad (hdr)
+- fix --interpolate flag to vipsthumbnail, thanks Lovell
+
+18/1/14 started 7.38.0
+- version bump
+
+19/10/13 started 7.37.0
+- redone im_rotate_*mask45(), im_gauss_*mask*(), im_log_*mask(), im_dilate(),
+ im_erode(), im_rank_image(), im_compass(), im_linedet(), im_gradient(),
+ im_convsep(), im_convsep_f(), im_fastcor(), im_spcor(), im_sharpen()
+ as classes
+- im_gradcor() deprecated
+- vips_init() now does some ABI compat checking, though this change requires
+ an ABI break
+- add "interlace" option to vips_jpegsave()
+- remove vips_image_copy_fields() and vips_demand_hint() and add
+ vips_image_pipeline() to do both jobs
+- vipsthumbnail allows non-square bounding boxes, thanks seth
+- add vips_matrixprint()
+- add @point subsample mode to vips_subsample()
+- im_contrast_surface() deprecated: it was slower than calling conv a few
+ times
+- radiance load supports sequential read
+- rewritten radiance decode is much faster
+- add vips_crop(), a synonym for vips_extract_area()
+- rename vips_gammacorrect() as vips_gamma(), now takes 1 / exp
+- vips_gamma() works for any format
+- add --linear mode to vipsthumbnail
+- support XYZ as a PCS for vips_icc_import() and vips_icc_export()
+- add --strip option to jpegsave
+- added vips_gaussblur() convenience function
+- added --vips-profile, records and dumps thread timing and memory use info
+- added vipsprofile, visualises --vips-profile output
+- auto-vectorization-friendly inner loops
+- added vips::init() and vips::shutdown() to C++ API
+- reuse pixel buffers on sharing to reduce mem cycling
+- conv is SMALLTILE, huge mem use saving on wide images
+- vipsthumbnail has a --crop option
+- remove video4linux1 code, it was useless on all modern linuxes
+- redone freq filter builders as classes
+- redone im_fwfft(), im_invfft(), im_freqflt(), im_disp_ps(), im_fractsurf(),
+ im_phasecor() as classes
+- vips_colourspace() allows B_W, GREY16, RGB16 as source / target
+- added vips_thread_shutdown(), thanks Lovell
+- vips_linear() has a uchar output mode
+- redone im_cntlines(), im_rank() as classes
+- move im_zerox() to deprecated, it wasm't very useful
+
+9/1/14 started 7.36.6
+- fix some clang compiler warnings
+
+20/11/13 started 7.36.5
+- better cache sizing in unbuffered sequential mode
+- allow larger tile_size in dzsave
+- remove use of PATH_MAX to help gnu hurd
+- fix vips_hist_match()
+
+15/11/13 started 7.36.4
+- improve compat with im_init_world()
+
+18/10/13 started 7.36.3
+- fix compiler warnings in ubuntu 13.10
+- reverse similarity rotation direction to match the convention used
+ elsewhere in vips
+- fix blocked caching of sequential load operations
+- fix cache flags
+- fix --delete option to vipsthumbnail
+
+10/10/13 started 7.36.2
+- better jpeg startup
+- rename jpeg bool type to reduce confusion between libraries
+
+3/10/13 started 7.36.1
+- fix to help OS X build
+
+3/10/13 started 7.36.0
+- version bump
+
+1/7/13 started 7.35.0
+- added vips_matrixload() and vips_matrixsave(), load and save vips mat format
+- rename image arrays as image matrices ... INTERPRETATION_ARRAY ->
+ INTERPRETATION_MATRIX etc.
+- rewrite im_buildlut(), im_identity*(), im_maplut(), im_falsecolour(),
+ im_gammacorrect(), im_histgr(), im_histcum(), im_histnorm(), im_heq(),
+ im_histnD(), im_histindexed(), im_histspec(), im_invertlut(), im_lhisteq(),
+ im_stdif(), im_project(), im_profile(), im_tone_build*(), im_mpercent*(),
+ im_ismonotonic() as classes
+- vips_hist_local(), vips_stdif() do any number of bands
+- thin vips8 wrapper for im_histplot()
+- added vips_error_freeze() / vips_error_thaw()
+- used freeze() / thaw() to stop file format sniffers logging spurious errors
+- vipsthumbnail uses embedded jpg thumbnails if it can
+- rename vips_diag() as vips_info(), add --vips-info flag
+- deprecate im_hsp()
+- added vips_webpload(), vips_webpload_buffer(), vips_webpsave(),
+ vips_webpsave_buffer(), vips_webpsave_mime()
+- tiff reader allows separate planes for strip read
+- tiff reader and writer allow many more formats, eg. 32-bit int, complex, etc.
+- tiff reader and writer allow any number of bands
+- added vips_image_new_matrixv()
+- dzsave basename param now called filename, so you can use .dz as a
+ destination (basename is still there but deprecated)
+- new _UNBUFFERED sequential mode saves memory in some important cases
+- vips_conv() is a simple wrapper over the old convolution functions
+- new optimize_coding param for jpeg write produces optimal Huffman tables,
+ thanks Lovell
+- im_tone_map() and im_tone_analyse() deprecated
+- new --band arg to vips_maplut() replaces im_tone_map() functionality
+- added vips_similarity(), simple wrapper for vips_affine() that lets you
+ give a scale and rotate
+
+3/7/13 started 7.34.2
+- lower priority for Matlab load to reduce segvs from Mat_Open(), thanks
+ Michael
+- null-terminate libexif strings, thanks Mike
+- openslide always outputs solid pixels
+
+28/6/13 started 7.34.1
+- fix morphological operators on non-uchar images
+- remove any ICC profile when we use vips to go to srgb
+
+7/6/13 started 7.34.0
+- version bump
+- oops, VImage.PIL_mode_from_vips() failed for CMYK, thanks Alessandro
+- fix no-pango build
+- add im_vips2dz(): run the deepzoom writer from vips7
+- vips_magickload() has an option to read all images in a sequence
+- redo im_make_xy(), im_*eye(), im_zone*(), im_sines() as classes
+- added vips_pngload_buffer()
+- faster --centre option to dzsave, thanks Kacey
+
+12/3/13 started 7.33.0
+- vipsthumbnail lets you specify the sharpening mask
+- turn off caching for im_copy()/vips_copy(), we use copy to stop sharing, and
+ it's cheap so caching doesn't help anyway
+- auto rshift down to 8 bits on save, if necessary
+- im_gaussnoise(), im_copy_file(), im_grid(), im_scale(), im_scaleps(),
+ im_wrap(), im_rotquad(), im_zoom(), im_subsample(), im_msb(), im_text(),
+ im_system(), im_system_image()
+ redone as classes
+- add --angle option to dzsave
+- another vips_shrink() fix argh
+
+14/5/13 started 7.32.4
+- icc import and export could segv on very wide images
+- fix centos 5 build, thanks re-boot
+
+16/4/13 started 7.32.3
+- rename GETTEXT_PACKAGE as vips7.32 to help Debian (thanks Jay)
+- added "persistent" option to tilecache
+
+12/3/13 started 7.32.2
+- removed some left-over debugging code from configure.ac
+- better handling of args without values, thanks Ruven
+- better error messages from vips.c
+- fix demand hints so "vips shrink" works again, thanks Jan
+- im_jpeg2vips.c builds without jpeglib.h, thanks Alessandro
+
+6/2/13 started 7.32.1
+- fix --without-lcms, thanks speckins
+- updates to licence, thanks Benjamin
+- remove "fred" from dist
+- better bootstrap on OS X
+
+22/1/13 started 7.32.0
+- tilecache in threaded mode could deadlock if the downstream pixel source
+ raised an error (thanks Todd)
+- fix another dzsave corner-case (thanks Martin)
+- neater output for "header"
+- added VIPS_META_LOADER: record the loader name
+= header displays this loader hint
+- vipsthumbnail is better at cache sizing
+
+31/8/12 started 7.31.0
+- redone im_Lab2XYZ(), im_XYZ2Lab(), im_Lab2LCh(), im_LCh2Lab(), im_UCS2LCh,
+ im_LCh2UCS(), im_XYZ2Yxy(), im_Yxy2XYZ(), im_float2rad(), im_rad2float(),
+ im_Lab2LabQ(), im_LabQ2Lab(), im_Lab2LabS(), im_LabS2Lab(), im_LabQ2LabS(),
+ im_LabS2LabQ(), im_LabQ2disp(), im_XYZ2disp(), im_disp2XYZ(),
+ im_icc_import*(), im_icc_export*(), im_icc_transform*(), im_dE_fromLab(),
+ im_dECMC_fromLab(), im_dE00_from_Lab(), im_icc_ac2rc() as classes
+- added vips_colourspace(), vips_colourspace_issupported(), replaces all
+ derived conversions
+- faster and more accurate sRGB <-> XYZ conversion
+- support 16-bit sRGB import and export
+- rename UCS colourspace as CMC
+- dzsave can write zoomify and google maps layout as well
+- tilecache supports threaded access, so openslide read now threads
+- openslide2vips gets underlying tile size from openslide
+- embed has 'background' option
+- dzsave --layout google has a @background option
+- dzsave has a --depth option
+- update for new glib threading API
+- remove no threads option, glib no longer support it
+- better --help output for vips driver prog
+- vipsthumbnail -o allows absolute file names
+- much better exif handling for jpg images (thanks Gary)
+- preserve jpeg app13 (photoshop ipct)
+- vips_max() / _min() track the top n maxima / minima
+- deprecate im_maxpos_avg(): too specialised to be worth maintaining
+- deprecate im_linreg(): easily done by combining other operators
+- deprecate im_point(): easily done by combining other operators
+- add binary complex operations, with cross_phase as the only one so far
+- added vips_bandbool(), with vips_bandand(), _bandor(), _bandeor() as
+ convenience functions
+- added scRGB colourspace, linear light float space with sRGB primaries
+- all interpolators use corner convention ... we had round-to-nearest in
+ several of them before, causing a range of annoying problems
+- redone im_affine*() as a class
+- added input space displacement to affine
+- VipsArea is threadsafe
+- dzsave has a --centre option
+
+31/12/12 started 7.30.8
+- png icc profile write was broken
+
+31/12/12 started 7.30.7
+- better option parsing for "vips", thanks Haida
+- small fixes to help OS X
+- backported threaded tile cache from next version, im_tile_cache() now
+ uses it to prevent a deadlock, see comment there
+
+14/11/12 started 7.30.6
+- capture tiff warnings earlier
+
+14/11/12 started 7.30.5
+- fix libtool version mess up (thanks Benjamin)
+
+2/10/12 started 7.30.4
+- remove options from format string in .dzi (thanks Martin)
+- vipsCC.pc required the wrong version of vips (thanks Alessandro)
+- larger max tile size for dzsave
+- linecache is 50% larger to leave some slop room
+
+13/9/12 started 7.30.3
+- linecache sized itself too large
+- fix a compile failure if libtiff was not found (thanks Martin)
+- dzsave did not work for images with an odd number of scanlines
+ (thanks Martin)
+
+4/9/12 started 7.30.2
+- sequential stops all threads on error
+- sequential delays ahead threads rather than blocking them completely
+
+6/8/12 started 7.30.1
+- fixes to dzsave: shrink down to a 1x1 pixel tile, round image size up on
+ shrink, write a .dzi file with the pyramid params, default tile size and
+ overlap now matches the openslide writer
+- wrap VipsInterpolate for C++
+- so affinei and affinei_all appear in Python
+- be more cautious enabling YCbCr mode in tiff write
+- add "DEPRECATED" flag to arguments
+- jpeg load/save note and use the preferred resolution unit
+- better error msgs for enum args
+- fix compiler warnings in production build (thanks Dmitry)
+- fix spurious warnings about exif updates
+- VipsSequential has an integrated cache and stalls out of order threads
+- add a line cache ... sizes up dynamically with request size
+- tilecache / linecache use a hash table not a linear list
+
+20/7/12 started 7.30.0
+- support "rs" mode in vips7
+- add --vips-version cmdline arg
+- fix --without-tiff / exr / jpeg / png / magick
+- add --vips-fatal flag
+
+19/3/12 started 7.29.0
+- sanity-check PNG read geometry
+- nearest-neighbor interpolation rounds coordinates to nearest instead of
+ rounding down (thanks Nicolas)
+- add dzsave, save in deep zoom format
+- rework im_shrink() as a class
+- remove im_rightshift_size(), just a convenience function now
+- vipsthumbnail no longer removes profiles by default
+- much more gentle sharpening in thumbnails
+- added "minimise" signal, used by tilecache to drop
+- add :seq support to im_tiff2vips(), im_jpeg2vips() ... helps ruby-vips
+- better thread safety for vips8 operation dispatch
+- better thread safety for upstream / downstream image linking
+- added "rs" open mode, removed "rd"
+- added vips_operation_get_flags() ... system for attaching sets of flags to
+ operations
+- added VIPS_OPERATION_SEQUENTIAL flag
+- vips8 command-line interface uses this to turn sequential mode on
+ automatically when possible
+- better handling of input files in vips7 command-line interface
+- sequential can skip ahead, so extract / insert are now seq
+
+16/7/12 started 7.28.10
+- wopconst was broken
+- vips_sign() was broken
+- png save compression range was wrong
+- more/moreeq was wrong
+- vips7 ppm save with options was broken
+- don't cache write operations
+
+18/6/12 started 7.28.9
+- slightly more memory debugging output
+- remove references to the static bicubic interpolator from the docs
+- fix temp file handling on Windows --- was breaking for non-vips files
+ over 100mb
+- better support for using images from multiple threads
+
+18/6/12 started 7.28.8
+- fixes for centos5 portability
+
+18/6/12 started 7.28.7
+- add vips_flatten() -- flatten RGBA to RGB
+- better alpha handling in PNG load
+- don't save RGBA PNG as CMYK JPG (thanks Tobsn)
+- fix a crash with malformed jpg files (thanks Grigoriy)
+- vipsthumbnail enables sequential mode more and caches lines better
+
+19/4/12 started 7.28.6
+- better resolution unit handling in deprecated im_vips2tiff()
+- use TIFF_CFLAGS output from pkg-config (thanks Jay)
+- much faster vips_argument_map()
+- make jpeg pyramids work with tiff4
+- tiff loader always offers THINSTRIP (thanks Diuming)
+- add "nocache" operation flag, set for sequential load (thanks Diuming)
+- fix a crash in the tiff reader for huge values of RowsPerStrip (thanks
+ Nicolas)
+- remove use of G_DEFINE_BOXED_TYPE() to help compat (thanks Jake)
+
+19/4/12 started 7.28.5
+- ifthenelse blend mode was broken
+- small blend speedup
+- default to libtiff-4
+
+17/4/12 started 7.28.4
+- up max buffer size for vipsbuf
+
+6/4/12 started 7.28.3
+- vips_divide() failed for int arguments
+- fix warning for unused vips7 gvalue argument
+- fix openslide read: always return png-style rgba, im_argb2rgba() becomes a
+ NOP
+- cast to unsigned int now removes <0 values
+- vips7 interface to openslide now supports :,level,associated options (thanks
+ Benjamin)
+- make vips8 cache smaller
+- more accurate progress reporting
+
+13/3/12 started 7.28.2
+- xres/yres tiffsave args were broken
+
+13/3/12 started 7.28.1
+- add ICC profile read/write for png files
+
+30/1/12 started 7.28.0
+- version bump
+- added vips_foreign_find_save_options()/vips_foreign_find_load_options()
+- delayed write to foreign via a "w" image was not working
+- support operations with many returns in Python
+- sequential read mode
+- better im_shrink()
+- added vips_sequential()
+- new vips_sink_memory() keeps read ordering
+- tiff, jpeg, png readers support sequential read
+- max/min avoid NaN
+- oop, histnorm was broken by the new vipsstats
+- never use IM ping to get a header, fixes BMP load
+- set @filename for non-vips formats in vips7 compat layer
+- make Xres/Yres double
+- completely disable debug by default in production builds
+
+20/8/11 started 7.27.0
+- version bump for new dev cycle
+- im_subtract(), im_avg(), im_min(), im_minpos(), im_copy(), im_embed(),
+ im_flophor(), im_flipver(), im_insert(), im_insert_noexpand(), im_lrjoin(),
+ im_tbjoin(), im_extract_area(), im_extract_bands(), im_extract_areabands(),
+ im_replicate(), im_clip2fmt(), im_gbandjoin(), im_bandjoin(), im_invert(),
+ im_lintra(), im_lintra_vec(), im_black(), im_rot90, im_rot180(), im_rot270()
+ im_sintra(), im_costra(), im_tantra(), im_asintra(), im_acostra(),
+ im_atantra(), im_exptra(), im_exp10tra(), im_logtra(), im_log10tra(),
+ im_abs(), im_sign(), im_max(), im_maxpos(), im_deviate(), im_divide(),
+ im_multiply(), im_stats(), im_measure(), im_recomb(), im_floor(), im_ceil(),
+ im_rint(), im_equal*(), im_notequal*(), im_less*(), im_lesseq*(), im_more*(),
+ im_moreeq*(), im_remainder*(), im_and*(), im_or*(), im_eor*(), im_shift*(),
+ im_pow*(), im_exp*(), im_ifthenelse(), im_blend(), im_c2amph(), im_c2rect(),
+ im_bandmean(), im_c2real(), im_c2imag(), im_ri2c(), im_jpeg*2vips(),
+ im_vips2jpeg*(), im_tiff2vips(), im_vips2tiff(), im_exr2vips(),
+ im_fits2vips(), im_vips2fits(), im_analyze2vips(), im_raw2vips(),
+ im_vips2raw(), im_magick2vips(), im_png2vips(), im_png2*(), im_ppm2vips(),
+ im_vips2ppm(), im_mat2vips(), im_rad2vips(), im_vips2rad()
+ redone as classes
+- added argument priorites to help control arg ordering
+- generate has a 'stop' param to signal successful early termination
+- added optional output args, eg. x/y for min
+- CLI supports optional output args
+- in im_vips2tiff, enable YCbCr compression for jpeg write
+- VipsMin stops search early if it can
+- C API supports optional output args
+- switch back to int-valued operations
+- add the operation cache, various --vips-cache-* flags
+- fallback vips_init()
+- vips_tracked_malloc() tracks allocation size and can report total mem usage
+- cache limits, drop, init, flush plus command-line controls
+- remove dmalloc support, was never used and valgrind is better
+- im_csv2vips() allows quoted strings, including escaped quotes
+- added vips_shutdown()
+- added --vips-leak flag
+- more VipsImage props
+- added vips_image_write(), old one becomes vips_image_write_to_file()
+- added vips_region_paint_pel()
+- added VipsArea as a public struct
+- added array members and arguments
+- added nary
+- remove VipsPool, vips_object_local_array() is much better
+- cache.c now drops if you have too many open files
+- CLI args to change max files
+- new format for handling exif tags
+- switch SMALLTILE to 128, 512 was just too big
+- oop mode "rd" was not always being used for images
+- added ARRAY interpretation for images
+- VipsStats tracks minpos/maxpos as well
+- moved mask/ to deprecated
+- use atexit() to call vips_shutdown()
+- set _O_TEMPORARY on delete-on-close temp images if possible
+- unlink temps on rewind on *nix, less likely to leave temps on a crash
+- added complex conj as a basic operation
+- rect/polar/conj work on any format, not just complex
+- new VipsFile system for load/save in image formats
+- options now introspectable, try "vips jpegsave"
+- copy swap uses glib byteswap macros, about 2x faster
+- edvips can change vips header byte ordering
+- "header" is terse by default
+- "header" outputs filenames if working on many files
+- added openslide support (Benjamin Gilbert)
+- allow new-style load/save options in filenames to
+ vips_image_new_from_file() etc.
+- VipsFormat is deprecated
+- remove outchecks from documented API
+- support gobject-introspection
+- new Python binding based on gobject-introspection
+- only spot options at the end of arg strings
+- add vips_cache() as a vips8 operator
+- remove the old fft fallback
+- remove fftw2 support
+- much faster im_draw_smudge()
+
+14/1/12 started 7.26.8
+- interpolate CLI args were broken (thanks speckins)
+
+5/12/11 started 7.26.7
+- lazy read from tiled tiff from layers other than 0 was broken
+- optional args to vips_call*() do not work, disabled (fixed correctly in
+ master)
+- address calculations in files over 4gb were broken on 32-bit platforms
+ (broken since March 2011, oops)
+
+12/10/11 started 7.26.6
+- NOCACHE was not being set correctly on OS X causing performance
+ problems with large files
+- update Orientation exif tag on jpeg write
+
+12/10/11 started 7.26.5
+- jpeg read/write copies over XMP data
+- handle offset correctly in separable convolutions (thanks Nicolas)
+- macros for class arg boilerplate
+- class arg order set by new 'priority' param
+- VipsExtend, VipsDirection enums added
+
+12/9/11 started 7.26.4
+- fallback vips_init()
+- im_openout() compat stub was wrong, breaking ruby-vips
+- vips_class_map_concrete_all() needed a compat macro too
+- vips_class_map_all() was broken
+
+10/8/11 started 7.26.3
+- don't use G_VALUE_COLLECT_INIT(), many platforms do not have a glib this
+ recent
+- don't leave image->kill set when we detect termination
+- test for a working C++ compiler, disable C++ parts of none found
+
+10/8/11 started 7.26.2
+- oops, im_benchmark.c had some stuff turned off
+- configure option --without-cfitsio was broken (thanks Mike)
+
+26/7/11 started 7.26.1
+- doc fixups
+- oops, ==0 missing from a strcmp() in vips7compat
+- fixed a race in im_XYZ2Lab() table build
+- added im_concurrency_get() to operation db
+- better benchmarkn.sh runs for the correct number of CPUs automatically, runs
+ three times for each one, and just reports the fastest
+
+26/7/11 started 7.26.0
+- version bunp for 7.26
+- various fixes to get win32 and OS X building
+
+6/12/10 started 7.25.0
+- attach the jpeg thumbnail and multiscan fields (thanks Mike)
+- faster tiff read for some common cases
+- faster im_tile_cache()
+- if we use C++ in libvips, add -lstdc++ to vips-7.xx.pc
+- im_vips2png() / im_png2vips() set / get png resolution (thanks Zhiyu Wu)
+- updated README
+- don't use tables for bilinear on float data for a small speedup (thanks
+ Nicolas Robidoux)
+- no tables for uchar either, about a 15% speedup (thanks Nicolas)
+- dmask write was broken
+- lr/tbmerge() cast images to match, like im_insert()
+- lr/tbmosaic() work for any mix of image formats / bands
+- removed ancient balance stuff from im_lr/tbmosaic()
+- gtk-doc for mosaicing
+- add im_fits2vips() to the operation database
+- im_fits2vips() is lazy and much faster
+- im__file_open_write() / _read() has a flag for text_mode, get rid of all the
+ remaining fopen()s
+- move cooc_* and glds_* to deprecated
+- move im_dif_std() to almostdeprecated
+- move im_simcontr() to almostdeprecated
+- add im_sines() to operation db
+- move im_spatres() to almostdeprecated
+- done gtk-doc for other
+- --vips-progress tells you about nthreads, tile size, nlines
+- gtk-doc for interpolate
+- move im_stretch3() to deprecated
+- move im_clamp() to deprecated
+- gtk-doc for video ... all operators done! amazing argh
+- set MAP_NOCACHE on OS X, otherwise performance dives off a cliff with
+ files larger than memory
+- removed man pages, we are all gtk-doc now
+- im_jpeg2vips() ignores weird APP1 chunks
+- im_add() for int/uint was broken
+- im_ri2c() was broken
+- added VIPS_FORMAT_BIGENDIAN format flag
+- moved IMAGE and REGION to VipsImage and VipsRegion, classes over VipsObject
+- Rect -> VipsRect
+- libpng-1.5 supported
+- better png read for 1-bit and palette images
+- fits write
+- better fits metadata support
+- renamed all header fields, old names still supported, hopefully
+- all of iofuncs moved to vips_ namespace
+- lots of old iofuncs API moved to deprecated
+- added VipsOperation, an abstract base class for all vips operations
+- added VipsAdd, the first operation object
+- im_tiff2vips() int/uint mixup for rows_per_strip, thanks Bubba
+- removed the links feature, won't work with vips8
+- got rid of the tools/ subdirs
+- added im_bufjpeg2vips()
+- tiff reader can do 1, 2, 4, 8 bit palette images
+- tiff palette read can do mono images
+- im_bufjpeg2vips() has a "header_only" parameter
+- added vips_image_get_data()
+- updated German translation (thanks Chris)
+- fixed typo in im_conv() overflow estimation which could cause errors
+- vips.c has new action syntax, knows about vips8 operations
+- add now has sizealike
+- vips7 binops all do sizealike too, also gbandjoin and ifthenelse
+- new API is now functional
+- vips.c generates GOption flags for vips8 operations
+- added im_gauss_dmask_sep()
+- laplacian generator lost -ve lobes for large sigma
+- added im_aconv(), approximate convolution
+- bumped smalltile to 512x512 for testing
+- added VipsPool, got rid of floating refs again, argh
+- VIPS_EXEEXT is now part of the exported API
+- im_blend() also does sizealike, oops
+- jpeg write was not inverting CMYK, thanks Ole
+- im_falsecolour() converts to mono 8-bit for you
+- im_icc_import*/export*() cast inputs for you
+- im_vips2tiff() uses im__temp_name() for intermediates
+- added vips_wrap7 ... wrap up vips7 operations as vips8 classes
+- man pages are back for commands
+
+30/11/10 started 7.24.0
+- bump for new stable
+- added im_dmask2imask(), im_imask2dmask()
+- im_rotate_*mask90() can do masks of any size (thanks Adam Turcotte)
+
+18/7/10 started 7.23.0
+- im_vips2bufjpeg() writes to a linked list, so it will work for any size
+ image and header
+- added im_vips2bufpng()
+- use GetTempPath() to pick a temp dir on Windows
+- added "rd" mode to im_open()
+- vipsthumbnail and vips use "rd"
+- im_divide spots /0
+- remove liboil dependency, we will use Orc instead
+- various small cleanups (thanks Tim)
+- add lcms2 support
+- VImage(filename) defaults to "rd" mode
+- revise window_offset / window_size, again
+- fix a mixup with ANY hints that caused performance problems on the main
+ benchmark
+- rewritten im_circle as im_draw_circle, im_circle moved to almostdeprecated
+- added IM_TYPE_RW args for inplace ops --- nip2 uses this to wrap inplace ops
+ automatically
+- special-case 3x3 masks in im_conv() for a 20% speedup
+- add IM_TYPE_RW flag for im__rw_image, helps nip2 auto-wrap inplace ops
+- im_insertplace() casts and bandalikes
+- copy iconv.m4 and friends in bootstrap, thanks Mike
+- moved the stupid _copy() versions of the inplace ops to deprecated, since
+ nip2 can call inplace ops directly now
+- added im_draw_rect(), moved im_paintrect() to deprecated
+- added im_draw_image(), moved im_insertplace() to deprecated
+- added im_draw_line(), now clips, moved im_fastline() to deprecated
+- added im_draw_line_user(), now clips, moved im_fastlineuser() to deprecated
+- added im_draw_mask(), now wrappable, moved im_plotmask() to deprecated
+- added im_draw_point(), moved im_plotpoint() to deprecated
+- added im_read_point(), now partial, moved im_readpoint() to deprecated
+- added im_draw_smudge(), moved im_smudge() / im_smear() to deprecated
+- convolution functions support complex images
+- im_blend() can have any format condition image and it's converted to uchar
+- security fix for vips-7.23 wrapper script (thanks Jay)
+- im_affine() has a larger safety margin
+- fix gtk-doc warnings
+- small mask load/save improvements
+- mask gtk-doc done
+- add cfitsio dependency
+- add FITS reader
+- land the vector branch and the orc dependency ... we have SSE
+ erode/dilate/add/conv
+- add IM_SWAP
+- dilate/erode do (!=0) on non-uchar images
+- add multipass Orc to im_conv(), 3.5x faster for 5x5 mask
+- im_profile() works for any image format, any number of bands
+- im_rank_image() works for mix of formats, bands
+- morph gtk-doc done
+- oops, missing braces in debug.h and util.h, thanks Laurence
+- update C++/Python binding
+- oop, bool constants are always (int) now, so (^-1) works for unsigned types,
+ thanks Nicolas Robidoux
+- much lower memuse for im_cache() in complex pipelines
+- im_scale_dmask() normalises to 20, not 100 ... we hit the fast
+ conv path more often
+
+12/5/10 started 7.22.2
+- the conditional image of ifthenelse can be any format, a (!=0) is added if
+ necessary
+- oops vipsthumbnail sharpening was turning off for integer shrinks,
+ thanks Nicolas Robidoux
+- im_vips2jpeg() could fail for very small images (thanks Tim)
+- threadpool wasn't stopping on allocate errors (thanks Tim)
+- vips_sink_disc() could block if allocate failed (thanks Tim)
+
+12/5/10 started 7.22.1
+- fix a problem with tiff pyramid write and >1cpu, thanks Ruven
+- constant ops clip to target range
+- oops, moreconst and moreeqconst were the same
+- better buffer handling in sinkdisc for single-line images
+- less chatty errors from "vips"
+- oops, don't rename "copy_set" as "copy_", thanks Ole
+
+12/5/10 started 7.22.0
+- bump and rename
+- vipsthumbnail has a manualpage and sharpens correctly
+- more interpolator work
+- fixes to --disable-cxx mode (thanks Mike)
+- added German translation, thanks Chris Leick
+- fixed typos in some messages, thanks Chris Leick
+- fix gettext startup
+- all "colour" in messages changed to "color", have a proper en_GB
+ translation file
+- vipsthumbnail delete profile failed if there was a profile
+- interpolate cli unref was broken
+- more accurate, slightly faster bilinear and bicubic (thanks Nicolas Robidoux)
+
+21/3/10 started 7.21.3
+- added progress feedback to threadpool
+- --vips-wbuffer2 switch does all wbuffer use now
+- im_wbuffer2() renamed as vips_discsink(), some cleanups
+- im_gammacorrect() can do 16-bit images too
+- im_histplot() could fail for signed int histograms
+- im_fwfft() and im_invfft() could free their output image too early
+- added im_local_imask(), im_local_dmask()
+- added im_mpercent_hist()
+- im_maplut() casts the index image to one of the uint types
+- fixed a couple of /0 problems with scale == 0 masks
+- set G_LOG_DOMAIN to VIPS so we can use g_warning etc.
+- added VIPS_DEBUG_MSG() macro
+- --vips-wbuffer2 turns on threadpool for im_iterate as well
+- im_vips2tiff() uses vips_sink() instead of threadgroup
+- strip out threadgroup
+- add --enable-debug=xxx flag
+- im_iterate() -> vips_sink()
+- better number-of-bands detection for im_magick2vips()
+- added im_get_argv0()
+- added PFM read / write
+
+16/1/10 started 7.21.2
+- "invalidate" is careful to keep images alive, so invalidate callbacks can do
+ im_close()
+- flood_blob could loop if start point == ink
+- added im_meta_remove()
+- added remove profile option to vipsthumbnail
+- added vips_bandfmt_iscomplex() and friends, im_iscomplex() and friends
+ deprecated
+- im_bandjoin()/im_gbandjoin() work with images of varying formats
+- added im_copy_native(), deprecated im_copy_from() and friends
+- im_check*() name rationalisation
+- finally removed old flood stuff
+- im_insert*() bandalike and formatalike
+- im_*join() bandalike and formatalike
+- im_ri2c() bandalike
+- im_vips2png() saves 16-bit PNGs, if necessary
+- vipsthumbnail has selectable interpolators, optional sharpen
+- moved a lot of stuff (eg. im_iscomplex()) from deprecated to
+ almostdeprecated to avoid breakage
+- im_csv2vips(): allow lines that end with EOF rather than \n
+- im_vips2tiff has a bigtiff option
+- oops, im_lineset() needs to ask for WIO of mask and ink
+- move cache invalidation to REGION, fixes a race
+- don't im_invalidate() after paint, it can cause horrible performance
+ problems ... for example, im_plotmask() used as the action operator for
+ im_fastlineuser() is terrible
+- instead, users of the inplace operations need to call im_invalidate() at the
+ end of a set of paint actions to trigger an update
+- parent/child renamed as upstream/downstream in DAG
+- set VIPS_ICC_DIR in configure
+- ICC profiles are looked for in VIPS_ICC_DIR as a fallback
+- im_render() mask image generation no longer triggers image calc
+- threadgroups scale output buffers with number of threads for smalltile ...
+ improves SMP scaling for narrow images on many-way machines
+- default to max number of processors (--vips-concurrency and IM_CONCURRENCY
+ set >0 can override) on linux and win32
+- better nprocs guesser
+- im_render() fixes to help the paintbox, some speedups too
+- added im_wbuffer2(), a new distributed threading system, and --vips-wbuffer2
+ to enable it, thank you Christian
+
+15/1/10 started 7.21.1
+- added "written" callbacks, used to implement write to non-vips formats
+
+26/11/09 started 7.21.0
+- branch for new dev cycle
+- argh, missing init from colour.c (thanks Peter)
+- argh, im_measure() was not looping over bands correctly (thanks Peter)
+- removed mmap_limit, we now always use windows ... reduces VM use hugely,
+ because mmap windows are freed when their regions are freed, while images
+ are only unmapped when they are closed
+- have a min bytes for mmap windows as well, so we don't make too many tiny
+ windows
+- im_disp2Lab() was broken
+- deprecated.h is now defined in terms of current functionality, rather than
+ repeating stuff
+- im_flood() and friends rewritten, typically 4x faster
+- removed --with-cimg option, added --disable-cxx
+- added im_system_image() (thanks Roland)
+- added postclose callbacks
+- added vipsthumbnail
+- oops, generate C++/Python wrappers for deprecated operations by default
+- read TIFF images strip-wise, not scanline-wise
+- better TIFF YCbCr reading (thanks Ole)
+- isanalyze generates fewer silly error messages
+
+26/11/09 started 7.20.3
+- updated en_GB.po translation
+- file_length is gint64 to avoid win32 breakage
+
+23/11/09 started 7.20.2
+- GETTEXT_PACKAGE now includes lib version number (thanks Jay)
+
+11/11/09 started 7.20.1
+- oop, im_clip2fmt() was missing PTOP flag, should get a small speedup
+- im_conv() / im_convf() didn't like all-zero masks
+- small updates to im_convf() from im_conv()
+- im_read_imask() produced an incorrect error message if passed a doublemask
+- rename im_convf(), im_convsepf() as _f()
+- vips.c drops _f suffix when overloading
+- regenerate C++ binding, don't make deprecated package
+
+9/11/09 started 7.20.0
+- removed vips-7.x.spec.in, shouldn't really have this in SVN
+- bumped version to 7.20
+- fixes to get "make dist" working again
+
+3/4/09 started 7.19.0
+- version bump
+- tiny conv speedup
+- catch lcms error messages
+- fix includes for gtk+-3.0
+- report virtual memory too in im__print_all()
+- cosmetic changes to nohalo
+- im_magick2vips() needs to invert alpha
+- now (more or less) passes -Wextra
+- added "fail" option to im_jpeg2vips: fail with an error on any warning
+ (thank you Ole)
+- started gtk-doc changes
+- renamed im_meta_get_type() and im_header_get_type() as
+ im_meta_get_typeof() and im_header_get_typeof() to prevent confusion with
+ GObject type definers (was breaking gtkdoc object scan)
+- revised more names, limited documented API
+- im_buildlut() could segv for non-zero based tables (thanks Jack)
+- VIPS_BUF_STATIC() does not take length arg
+- check for SetImageOption() so we work with GraphicsMagick too
+- "header" sets a non-zero exit code if anything failed
+- add and use im_check_uncoded() and friends
+- matlab load handles column-major and plane-separated images (thanks Mikhail)
+- JPEG save allows "none" for profile, meaning don't attach a profile
+- saner, simpler, faster typecasting for im_add(), im_subtract(),
+ im_multiply(), im_divide(), im_remainder()
+- im_remainder() has a float result for float types
+- im_measure() allows sel == NULL, meaning all patches
+- added "deprecated" package
+- faster, simpler, better im_max(), im_min, im_avg(), im_deviate()
+- im_max() returns true modulus, not square of modulus, for complex images
+- im_avg() works for complex, returning average modulus
+- im_system() fix (thanks Roland)
+- im_system() rewrite
+- im_maxpos()/im_minpos() are partial and work for complex
+- im_max()/im_min() are now convenience functions
+- im_maxpos_avg() handles complex and multi-band images
+- added im_point(), rewrite im_point_bilinear() in terms of this
+- close callbacks now happen *after* images have closed resources (such as
+ open files) ... this lets them delete temps and stuff. Expect breakage :(
+- added vips_interpolate_get_window_offset()
+- boolean revised: smaller, more general, faster
+- im_remainderconst_vec() renamed to im_remainder_vec() for consistency
+- added im_shift*_vec()
+- renamed im_eor_vec() as im_eorimage_vec() for consistency, also and, or
+- renamed im_eorconst() as im_eorimage_const() for consistency, also and, or
+- relational revised: smaller, more general, faster
+- im_blend()/im_ifthenelse() allows many-band conditional, 1-band then/else
+- im_blend()/im_ifthenelse() allows band and format to differ between then
+ and else parts
+- better im_check() functions
+- added im_flood_other() as start of simple segmentation operator
+- added im_label_regions()
+- im_printlines(), im_debugim() deprecated (use im_vips2csv() instead)
+- meta, header, callback, error, region, check, generate, memory gtkdocs
+- removed printlines tool, vips2csv is much better
+- removed other useless tools as well: debugim, binfile
+- fix up addr calcs on 64-bit machines with >2gb images and inplace ops
+ (thanks Christoph)
+- im_generate() checks that im_demand_hint() has been called for this image
+- im_jpeg2vips.c, set scale_num on shrink (thanks Guido)
+- heh argh reading history always stopped after the first line (thanks Haida)
+- added im_histindexed
+- new im_iterate() calls start and stop functions from workers so resources
+ they make are owned by the worker thread ... this makes it possible to have
+ start functions which create mutiple regions and therefore allows
+ im_iterate() to scan more than one image at once
+- threadgroup no longer has any default action, you must attach a work
+ function
+- added im_copy_file()
+- added im_insertset()
+- im_insertplace() allows small to be outside big
+- added im__colour_difference(), colour ops now work on any image format
+- added im_col_display_get_table(), so display tables are now shared by name
+- added im__colour_unary()
+- drop "set" postfix from names, so "insert" can now take a vector of positions
+- deprecate all the "_raw" variants, not really necessary now
+- removed "contrib", not very useful anymore
+- added im_header_as_string()
+- im_malloc()/im_free() now call g_try_malloc()/g_free() ... removes confusion
+ over whether to use im_free() or g_free() for things like im_header_string()
+- added im_history_get(), im_getexp(), im_printdesc() as wrapped functions ...
+ so you no longer need the "header" program
+- image vectors from Python work, woo
+
+25/3/09 started 7.18.0
+- revised version numbers
+- updated vipsmanual
+- revised manpages
+- removed name and "changed" from vipsobject since we don't use them yet
+- explicitly link with stdc++ for nohalo etc. stuff
+- wrap im_gauss_imask_sep in C++/Python
+
+6/3/09 started 7.17.3
+- revised nohalo
+- remove fading stuff from im_render() -- cleaner and simpler
+- configure spots support for "restrict"
+- reset dcm:display-range on magick read to help DICOM
+- saner im_buildlut() behaviour
+- added im_gauss_imask_sep()
+- allow open and view of truncated images (thanks Joe & Rachel)
+- revising rounding on im_affine*() coordinate transforms to make them more
+ stable
+- added Radiance write
+- added im_float2rad()
+- added IM_CODING_RAD, support where it makes sense (extract, flip, rotate,
+ etc.)
+- IM_PROGRESS env var
+- docs for rad2float and IM_CODING_RAD
+
+3/3/09 started 7.17.2
+- im_magick2vips.c: allow funky bit depths, like 14 (thanks Mikkel)
+- isradiance was returning TRUE too often
+- radiance loader now loads packed RGBE/XYZE instead of unpacking to float
+- added im_rad2float()
+
+11/10/08 started 7.17.0
+- merge vips-7.16 brach back into trunk
+- bumped version number to 7.17.0
+- re-added type.[hc]
+- added vipsinterpolate and im_affinei
+- added yafrsmooth interpolation
+- added yafrtest
+- added yafrnohalo
+- ubuntu 8.10 changes
+- interpolators get an output pointer, not region
+- tuning for bicubic
+- revised transform / clip code, we now do corner not centre
+- yafr-smooth reworked along the lines of bicubic
+- cleanups after yafr hacking
+- added affinei_all
+- don't set im_error() on failed callback
+- moved im_format_t to VipsFormat, now sits over VipsObject
+- IM_FORMAT_FLAG_PARTIAL -> VIPS_FORMAT_PARTIAL
+- updated docs
+- interpolators use type introspection
+- added vips --list classes, does formats too
+- include sys/param.h to get PATH_MAX in more places
+- added vips_format_get_flags()
+- oop, forgot to check for cancel during tiled tiff write
+- don't use mmap for tiff read: no performance advantage, chews up VM
+- VIPS_INTERPOLATE_SHIFT bumped to 12, we need the extra precision for u16 gel
+ data
+- added string->double transform for cmdline args
+- merged class-params branch back into trunk
+- IM_FREE() can do "const char*" variables
+- im_buf_t renamed as VipsBuf
+- added vips_object_to_string()
+- added "nickname" and "description" properties to VipsObject
+- shift/and/or/eor ops were broken for non-int types
+- added nohalo interpolator
+- updated format docs
+- IM_INPUT_INTERPOLATE() now used by affinei and affinei_all
+- added vips_object_new
+- resamplers/interpolators now in a resample package
+- removed yafrnohalo.c
+- added matio as a dependency
+- added Matlab save file read
+- added Radiance file read
+- better file-not-found messages
+
+11/9/08 started 7.16.3
+- oop typo in manpage for im_project()
+- doc fixes
+- returning non-zero from eval callbacks was not always stopping computation
+
+11/9/08 started 7.16.2
+- added --without-v4l option
+- added -no-undefined to libsrcCC build, so we get a libvipsCC.dll
+- removed the swig dependency: we include the generated bindings in the
+ distribution tarball
+
+6/9/08 started 7.16.1
+- trigger eval callbacks on tiled tiff write
+- added vips as an im_format_t
+- added im_format_write()/_read() convenience functions
+- more cleanups for the format API, argh
+- removed win32/ directory now mingw finally makes DLLs correctly
+- removed the windowed spcor for now, it has some edge effects
+
+24/8/08 branch for 7.16
+- renames and version numbers
+- load plgs from libdir as well as libdir/vips-x.x for compat
+- complex -> complex conversion was broken
+- refstring <-> gstring transforms
+- better behaviour with Magick non-presence
+- added --enable-links switch to configure ... we no longer make the bin/im_*
+ links by default
+- started a 'format' section in the docs
+- configure fails if no gettext found
+- revised po/
+- released as 7.16.0!
+
+25/5/08 fork for loadable image format branch
+- image load/save in non-vips format code moved to own dir
+- simple format searching added
+- some cleanups for vips load
+- im_open() simplified
+- add im_format_flags
+- only consider formats with a save method in im_format_for_name()
+- oops, format sort order was reversed
+- im_filename_suffix() includes "." in suffix
+- merge back into trunk for 7.15.1
+- remove im_ispng(), im_png2vips_header() etc. & friends
+- add "vips --list formats"
+- rename VBuf as im_buf_t for consistency
+- add type.[hc], start of new type system
+- removed man pages for IM_MIN, MAX and RINT to avoid case confusion on
+ OS X / win
+
+7/3/08 started 7.15.0
+- MAGIC constants should be tagged as unsigned
+- write MAGIC correctly on sparc/powerpc machines (thanks Joe)
+- oop, we were still making fade threads even when not fading
+- tiny cond jump fixes for valgrind in colour.c
+- remove -lstdc++ from libs, except on windows
+- push Magick cflags earlier in the include order to make it easier to pick
+ GraphicsMagick over ImageMagick (thanks Mikhail)
+- fix the en_GB translation
+- use meta to preserve resunit between tiff load and save
+- small doc improvements
+- read and write CMYKA tiff (thanks Doron)
+- performance improvements for morphology ops, esp. when zooming out
+- oop, im_render() was broken for mask == NULL
+- better support for multiple Python installs (thanks Jay)
+- better IM_SETSTR() stops some warnings
+- im_histcum() works for signed histograms
+- better rounding for im_conv(), im_convsep()
+- tiny speedup for im_conv()
+- better /0 test for remainderconst
+- revise i18n configure, get rid of intltool
+- command-line IMAGVEC input could segv with non-vips image output
+- added .tobuffer()/.frombuffer(), .tostring()/.fromstring() to Python binding
+- add PIL_mode_from_vips () and vips_from_PIL_mode () utility functions
+- update docs for new Python stuff
+- FIND_ macros no longer search for stuff, you have to specify prefixes if the
+ packages are not on the default path (or in $prefix). This avoids some
+ accidents on some platforms
+- configure prints a summary of optional packages found at the end
+- im_lhisteq() checks for window too small
+- added invalidate callbacks
+- now tests for MagickWand before ImageMagick (thanks Adam Turcotte)
+- added "-rotate" option to vips2dj
+- added man page for im_resize_linear
+- better jpeg-in-tiff YCbCr read (thanks Ole)
+- oops, invalidatefns were not being freed on im__close()
+- VMask() can init from std::vector, so Python can init from []
+- added IM_LIBDIR, im_guess_libdir()
+- load plugins from libdir/vips-x.x on startup
+- added meta get/set int/double/string/area/blob/GValue to C++ API
+- include time_t in vips.h, thanks Nicolas Robidoux
+- lock global image list (thanks lee)
+
+25/1/08 started 7.14.0
+- bump all version numbers for new stable
+- better CMYK JPEG read (thanks Ole)
+- add __str__ to VError in Python (thanks Ole)
+- revert the dynamic wrapping for Python :-( next version!
+- added VImage::convert2disc (thanks Ole)
+- you can now set the jpeg quality factor for tiff pyramids (thanks Joe)
+- you can now shrink jpegs during read, see "man im_jpeg2vips"
+- added CMYK JPEG write
+- optionally use GraphicsMagick (thanks Bob Friesenhahn)
+- look for MAGICKCORE_HDRI_SUPPORT (thanks Marcel)
+- set icc profiles in tiff pyramids explicitly (thanks Joe)
+- add --without-cimg configure option
+- add im_maxpos_subpel
+- make im_abs compile without liboil
+- add im_align_bands
+- fix type overflow in complex division
+- fix im_cross_phase and im_addgnoise (Tom)
+- updated docs, C++ and python
+- header no longer stops on error
+- C++ dummy2.cpp helps OS X linking
+
+12/12/07 started 7.13.3
+- added "include " to VImage.cc to help gcc 4.3
+- started moving the python binding to dynamic wrapping
+- added im_wrap(), im_wraptwo(), im_phasecor_fft(), im_cross_phase() (Tom)
+- memleak plugged in im_save_string_setf()
+- bugfix in and docs for im_gradcor() (Tom)
+- use Glib macros to make im_msb work on big-endian platforms (Tom)
+- use Glib macros to get rid of needless compile warnings (Tom)
+- fix type overflow in im_c2ps/im_abs (Tom)
+
+31/10/07 started 7.13.2
+- build cimg on windows fixes
+- various include cleanups, updated man pages
+- break im_wbuffer() out to a separate API
+- use im_wbuffer() to make im_vips2jpeg() compress in the background
+- also im_vips2png(), im_vips2tiff(), im_vips2ppm()
+- revised evaluation progress system
+- new evalstart/evalend/preclose callbacks fix over/underflow reporting
+- but the meaning of evalend has changed in a non-backwards-compatible way :(
+ use preclose instead ito get the old behaviour
+- added "--vips-progress" flag to turn on a simple eval progress tracker
+- make im_spcor[12] static, im_spcor is wrapper (Tom)
+
+28/9/07 started 7.13.1
+- vips2dj can print RGB images
+- oop, include missing
+- add protos for generate/iterate function args, fix warnings
+- add cimg package, we now have C++ source inside VIPS, sigh
+- added OUTPUT_DOUBLEVEC and OUTPUT_INTVEC, use for im_maxpos_vec() and friends
+
+29/8/07 started 7.13.0
+- we now have a trunk and the version is 7.13.x, woo!
+- move manpages into a separate man/ dir ... speeds up builds a lot on windows
+- don't install malkovich
+- don't fail on unknown args for python (thanks Simon)
+
+1/8/07 started 7.12.5
+- im_embed() is more general ... x and y can be negative
+- predicate.c is smaller and cleaner
+- libsrcCC link improvement from Pablo
+- support 32/64-bit ImageMagick as well (thanks Marcel)
+- better im_magick2vips() for Q8 ImageMagick
+- split repository to trunk/branches ready for a stable 7.12.x branch
+
+27/7/07 started 7.12.4
+- proto.h had vars called small, breaking on win32
+- more python fixing, we now have working matricies too
+
+17/7/07 started 7.12.3
+- fix to VImage.i for gcc 4.2 (thanks Damir)
+- eek, off by 1 for more than 1 band hists
+- needed a slightly larger worst-case buffer in im__b64_encode()
+- tiny cleanup for make_hI() prevents cond jump on ui in valgrind
+- --disable-threads was broken again
+- remove .svn dirs from dist
+- now passes distcheck again
+
+17/7/07 started 7.12.2
+- added im_bandmean()
+- added support for TIFFTAG_PREDICTOR (Andrey Kiselev)
+- fix TIFFOpen() mode snafu (Andrey Kiselev)
+
+11/5/07 started 7.12.1
+- memory.c abort()s with DEBUG
+- oops, im_bits_of_fmt() manpage was not being installed
+- im_histcum() can do all image types
+- updated NEWS
+- added im_csv2vips_header()
+- command-line csv read was broken (thanks Tom)
+- removed length limit on argument vectors (Tom)
+- added IM_PREFIX, configure-time install prefix
+- oop, turned off memory.c DEBUG
+- fix some bogus gcc 4.1 warnings with im_open_local_array()
+- better vips usage message
+- oops, IM_ANY missing from im_demand_hint() manpage (thanks Shahid)
+- just warn if plugins fail to load in im_init_world()
+- expose Vargv and make refblock public rather than private so that
+ subclasses of VImage can add vips-style member operations (thanks Pablo)
+- oops, im_initdesc() needed to have bbits set correctly (thanks Shahid)
+- make VError derive from std::exception more officially
+- woo, got exceptions working in SWIG
+- soname version bumped to 12.x.x
+- oops, added vector ops to Python
+- check for overflow of int in return of strtol in dispatch system (Tom)
+- add im_[di]mask_[xy]size to dispatch system (Tom)
+- add im_gradcor(), im_grad_[xy] (Tom)
+
+26/3/07 started 7.11.21
+- ooo, added %include "std_except.i" & friends to VError.i, VImage.i
+- im_init_world() is more lenient about recursive invocation
+- im_gbandjoin() falls back to im_copy() for 1 input image
+- race condition fixed in im_render.c (thanks Simon)
+- bump for 7.12!!!
+
+26/1/07 started 7.11.20
+- another fix to im_region_image() (thanks Mikkel)
+- tiny speed up to im_rect_includesrect()
+- avoid recursive invocation in im_init_world() (thanks Christian)
+- fix to extract_prefix (thanks Christian)
+- buffer cache is now per thread
+- combine buffer unref and ref in a single operation to reduce malloc/free
+ cycles
+- new internal API for passing regions between threads means we can remove
+ buffer locks
+- more buffer/region sanity checks, plus a memory barrier
+- lock around error buffer changes
+- im_vips2mask() was wrong for nx1 m-band images
+- liboil back to "test"
+- add buffer_cache_list to avoid GHashTable _insert()s
+- oop, --vips-concurrency was broken
+- renamed (in dispatch layer) im_and/or/eor_const -> im_and/or/eorimageconst
+ for consistency
+- C++ API wraps IMAGEVEC, DOUBLEVEC, INTVEC arguments
+- oop, IMAGE % vector was broken
+
+21/12/06 started 7.11.19
+- added im_linreg() (Tom)
+- various C++ API polishes, plus a bugfix (Dennis Lubert)
+- vips.spec split to devel and python too (Dennis Lubert)
+- be more explicit about sizeof(magic)
+- init magic to native order by default (thanks Dennis)
+- Hist becomes im_history_get()
+- new history mechanism is faster, uses much less memory, and removes
+ duplicate lines
+- added im_get_option_group()
+- added official im_concurrency_set()/_get()()
+- don't read bbits from vips files ... set ourselves from bandfmt
+- oops add RGB16 and GREY16 to C++ header
+- --list packages option to vips.c
+- updated docs to 7.12
+- oops, im_region_image() snafu was causing a lot of recomputation
+- make im_mpercent() suck a little less
+- EXIF save was a bit bOrked ... cause of mac crashes?
+- im_histgr(), im_heq(), im_hist() all number bands from zero now
+- fix stride in liboil calls
+- set RGB16 on 16-bit RGB ICC export
+
+29/11/06 started 7.11.18
+- added im_buffer_t so regions can share calculated pixels: 2-3x speedup on
+ the benchmark
+- im_region_local() -> im_region_buffer()
+- im_sharpen() order change to help sharing
+- im_invalidate() clears buffer caches
+- add sentinel attributes
+- add some missing im_demand_hint()s
+- paint ops invalidate the output image
+- fix nothread eval
+- raise threads limit to 1024 (thanks Christian)
+- manual redone
+- vipsCC python init() hooks
+- add liboil dependency
+- use liboil for im_abs(), im_add(), im_divide(), im_floor(), im_multiply(),
+ im_subtract(), im_lintra(), im_avg(),im_deviate()
+- quiet libtoolize test (thanks Tom)
+- im_benchmarkn now regrows image each time
+- strip meta from sample2.v ... saves a lot of mem (esp. Hist)
+- added im_isscalar() (Tom)
+- added IM_REGION_ADDR_TOPLEFT() (Tom)
+- reduce size of im_rightshift_size.c to help compile (Tom)
+- make im_stop_many(NULL) safe (Tom)
+
+24/11/06 started 7.11.17
+1;5Q
+- better benchmark script makes graphing easier
+- double-buffer image file writes
+- reuse write threads
+- clean up threadgroup / iterate / generate
+- added im_benchmarkn to make it easier to make a CPU-bound op on large
+ machines
+- im_cache() failed for cpus > 1
+
+1/11/06 started 7.11.16
+- moved im__convert_saveable() into im_copy() (thanks Christian)
+- missing gobject dependency (thanks Christian)
+- --enable-threads was broken (thanks Christian)
+- eval without theads was broken (thanks Christian)
+- LIBADD libvips.la to libvipsCC.la (thanks Simon)
+- benchmark.sh is now plain sh, not bash
+- set ORIENTATION_TOPLEFT in im_vips2tiff (thanks Josef)
+- oops, im_vips2csv() output separator was broken
+- added im_benchmark2
+- move XYZ2Lab LUT build outside the eval thread
+
+30/10/06 started 7.11.15
+- print leaked windows
+- oops, race condition in im_window_unref()
+- integrated im_region_window() into im_region_image(), tiny speed up
+
+6/10/06 started 7.11.14
+- ifthenelse and affine dhints revised
+- buildlut no longer outputs x cods
+- configure asks for glib >= 2.6 (we need GOption)
+- configure uses AC_TOOL_CHECK to find tool names to help cross-compiling.
+- better configure test for libexif
+- add C++ include ... include in a namespace
+- added im_benchmark / SMP benchmark script
+- add im_maxpos_avg() and im_point_bilinear() (Tom)
+- make im_region_free(NULL) safe (Tom)
+- link in manpages for im_contrast_surface (Tom)
+
+8/9/06 started 7.11.11
+- add im_norm_dmask()
+- removed old code for gradient and lindetect
+- internal decls split from proto.h to help SWIG
+- test for python and SWIG during configure
+- added python dir for the binding
+- python binding done!
+- oops, --without-python was broken (thanks Tom)
+- added python/test
+- add im_lu_decomp() im_lu_solve(), rewrite NR type functions in terms of these (Tom)
+
+23/6/06 started 7.11.10
+- still more im_affine() rounding/clipping tweaks
+- ignore "--" arguments to vips.c
+- im_init_world() also sets g_*_prgname() and loads plugins
+- add manpage for im_init_world() (oops)
+- error_exit() prints prgname
+- various cygwin fixes
+- fix cache thread assert failure (thanks Joe)
+- "header" now uses GOption, slightly different args, will loop over args
+- fixed assert() overenthusiasm in im_prepare()
+- im_csv2vips() now has separate whitespace / separator tables
+- add im_rightshift_size() (Tom)
+- add im_maxpos_vec(), im_minpos_vec() (Tom)
+- add im_norm_dmask() (Tom)
+- make im_free_[di]mask(NULL) safe (Tom)
+
+23/6/06 started 7.11.9
+- back on sourceforge CVS again
+- require openexr 1.2.2 or greater
+- range check xy on im_insert*() for sanity
+- VMask::invertlut decl removed (thanks Jean)
+- added \"all\" option to vips.c
+
+17/5/06 started 7.11.8
+- debrokened openexr read
+- added im_tile_cache()
+- added tiled read to im_exr2vips()
+- im_tiff2vips() now uses im_tile_cache() rather than its own cache ...
+ faster in some cases, less RAM use in some cases, saves 200+ lines
+- removed 'broken' read option from im_tiff2vips()
+- read/write doubles with g_ascii_strtod() and friends where appropriate
+- add a "thread" member to region to help sanity check region ownership
+- saner threadgroup fixes a race problem on gcc 4.0.3 / amd64
+- added im_vips2csv()
+- im_open() now does CSV read/write too
+- oops, broke vips main prog for function name in argv1 case
+
+22/4/06 started 7.11.7
+- split vips_png.c to im_vips2png.c and im_png2vips.c
+- added OpenEXR dependency
+- added im_exr2vips(), im_exr2vips_header()
+- added im_isexr(), im_open() knows about OpenEXR
+- added im_contrast_surface(), im_contrast_surface_raw() (Tom)
+- added im_msb(), im_msb_band() (Tom)
+- im_scale() sets Type on output
+- added RGB16, GREY16 types
+- im_*2vips() set these types if appropriate
+- configure fixes for mac
+- vips main prog uses GOption
+- im_icc_* locks around calls to cmsDoTransform() to avoid corruption on SMP
+ machines
+- add im_prepare_many() (Tom)
+
+10/3/06 started 7.11.6
+- typo in manpage and header for im_rect_dup() (Tom)
+- don't abort image load if XML read fails
+- added im_video_test() ... test video source
+- oops, lcms .pc finder was not working
+- clipping problem in im_affine() fixed (thanks Clare)
+- test for attr support in libmagick
+- im_text() returns an error for empty string
+- im_falsecolour() scale reversed
+- im_remosaic() could crash on bad mosaics
+- configure changes to fix --without-magick, lcms and fftw (but sadly we now
+ require .pc files for these libs)
+- im_vips2jpeg() automatically converts to 1 or 3 band sRGB uchar for write
+- also im_vips2png()
+- added im_project()
+
+20/2/06 started 7.11.5
+- added im_csv2vips()
+- commas in filename options can be escaped with a '\'
+- raise tile buffer limit (thanks Ruven)
+- im_spcor() and im_fastcor() have prettier borders
+- im_fastcor() returns sum of squares of differences, not sum of abs of
+ differences
+
+18/11/05 started 7.11.4
+- small win32 fixes, thanks Juan
+- added im_flood_blob_copy() ... a temporary hack
+- much faster im_histplot()
+- read RGBA palette-ized PNG images more robustly (thanks Tom)
+- turn on -ms-bitfields automatically for mingw
+
+26/9/05 started 7.11.3
+- better error recovery for im_binfile() file too large
+- all raw files now use mmap windows, so (eg.) ppm and analyze reads can go
+ >2GB
+- remove DISABLE_COMPAT ... you now have to define IM_ENABLE_DEPRECATED to get
+ broken #defines
+- fix to build without exif, thanks Chas
+- use native win32 API for seek()/truncate() to work with large files
+- use attribute to check printf-style args with gcc
+- fix gcc4 warnings
+- removed ebuild, since it's in gentoo now
+- im_magick2vips() sets meta from attributes (good for dicom)
+- im_magick2vips() writes many-frame images as tall thin VIPS images
+- im_histcum() was broken for vertical histograms
+- im_histnorm() is neater
+- simpler and faster inner loop for im_conv() and im_convf() avoids gcc4 bug
+- appendc() was reading past the end of the buffer on MSB machines
+
+13/6/05 started 7.11.2
+- im_copy_set() was messed up in 7.11.1
+- put into CVS, phew
+- fixed a rounding bug in im_affine() ... should no longer get black edges on
+ image resize
+- if TIFF open fails in im_open(), try going through libmagick
+- merge requires all bands == 0 for transparency (used to just check 1st
+ band)
+- 16 bit LAB TIFF read/write was wrong
+- new GType for refstring makes it visible from im_header_map()
+- jpeg loader attaches exif data (and human-readable meta fields)
+- jpeg saver writes any exif data
+- meta not wiped by im_*incheck() in a "w" image
+- meta keeps traverse order
+- now require glib >= 2.4
+- require libxml-2.0 for meta save and new history mechanism
+- no more .desc files, history saved in XML after pixel data
+- i/s/d meta fields saved there too
+- added base64 encode/decode
+- added blob header write
+- added a save string type: types which define transforms to and from the
+ save format get serialized
+- GValue meta API now exposed, since we can serialise anything
+- jpeg loader loads ICC profiles
+- jpeg saver saves ICC profiles from the VIPS header
+- src/header.c knows about meta system
+- added im_analyze2vips(), im_grid(), im_raw2vips()
+- extract/grid/replicate/zoom were not setting TRANSFORM flag
+- better falsecolour LUT
+- less stupid + more portable read/write of VIPS header
+- better im_updatehist()
+- jpeg load sets vips xres/yres from exif, if possible
+- jpeg save sets exif xres/yres from vips, if possible
+- icc_export and icc_transform attach profiles and intents to output images
+- added im_icc_import_embedded() to import with an embedded profile
+- split vips_jpeg.c into two, it was getting too big
+- added im_cp_descv(), im_cp_desc_array(), funcs use them
+- removed im_append_Hist() from API
+- fixed meta copy bug
+- better history copy, removed nonsense about 1st line of Hist being special
+- tiff read/write now reads/writes ICC profile from meta
+- edvips rewritten to remove stupidness, and can now set xml
+- header can now print xml extension block
+- IM_ prefix for colour temp names
+
+1/6/05 started 7.11
+- added im_copy_morph()
+- im_region_region() allows Bands and BandFmt to differ, provided
+ sizeof( pel ) is the same ... makes im_copy_morph() work
+- added im_meta*() functions (MW)
+- im_header_*() rewritten for meta
+- added im_header_exists(), im_header_map()
+- use pkg-config to find libpng and ImageMagick
+- added im_lineset()
+- added im_extract_areabands() (JF)
+- added im_copy_from() (JF)
+
+15/4/05 started 7.10.12
+- im_ifthenelse just evals left/right for region all zero/all one
+- also im_blend
+- swap g_setenv() back to plain setenv() so we work with glib 2.2
+
+9/4/05 JC started 7.10.11
+- docs no longer have broken links
+- fixed memleak in im_text()
+
+8/4/05
+- one bit tiff read was sometimes reading a byte too far in each scanline
+
+14/1/05 started 7.10.9
+- im_filename_split() will now usually work for filenames containing ':'
+ characters
+- added im_render_fade() for fancier nip2 image repaint
+- added "ccittfax4" as a TIFF compression option
+- fix all 64-bit compiler warnings
+- "," allowed as column separator in mask read
+- better at spotting singular matricies
+- small im_render() tidies
+- glib dependency reduced to just 2.0, but untested ... helps people building
+ on older systems who aren't interested in nip2
+- removing leading spaces from IMAGEVEC arguments
+- load non-interlaced PNGs more efficiently
+- 1 point mosaic functions work on more image types
+- better memory allocation debugging info
+- local memory on regions can shrink as well as grow
+- shut down threadgroups on render if no dirty tiles
+- limit number of simultaneous renders
+- higher mmap window threshold
+- allow max == -1 for unlimited render cache
+- 'priority' marks non-suspendable renders
+- im_embed() mode == 4 paints white pels
+- im_tiff2vips() was broken with --disable-threads
+- oops, im_errormsg() compat macros were GCC only
+- larger default tile size and strip height
+- tiff write sets PHOTOMETRIC_CIELAB for vips TYPE_LAB images ... so we can
+ write float LAB as well as float RGB (thanks Ruven)
+- also 16 bit LAB TIFF write
+- im_render() rewritten
+
+20/11/04 started 7.10.8
+- im_sharpen() is ~15% faster
+- more quoting for MAGICK finder
+- im_XYZ2Lab() uses a LUT rather than cbrt(), 5x faster
+- --disable-threads removes gthread dependency completely (thanks Simon)
+- intercept TIFF warnings as well as errors ... stops occasional libMagick
+ exceptions
+- add im_init_world() to im_init() as well to help backwards compat (thanks
+ Simon)
+- im_icc_present() function description was broken, thanks Jay
+- oops, libtool library versioning was wrong, thanks Jay
+- can now make TIFF pyramids of any non-complex image type (was uchar and LAB
+ only), thanks Ruven
+- 1st order mosaic code now works for LABQ too
+- build system changes to make "make distcheck" work
+- RPM .spec files fixed up and updated by configure (thanks Simon)
+- tiny cleanups for vdump
+- use g_setenv()/g_getenv()
+- tiny improvements to IM_FREE*()
+- tiny VImage debug print fixes (thanks Jay)
+- swap off_t for gint64 to fix LARGEFILE support on win32
+- computation feedback now uses gint64 for number of pels, so we give feedback
+ correctly on images with >2**31 pels
+- other small fixes for >2**31 pels in an image
+
+10/11/04 started 7.10.7
+- im_histnD() was not checking BandFmt (thanks Kirk)
+- improvements to threading system speed up non-vips output in some cases
+- use cbrt(x) where we can ... 10x faster than pow(x,1.0/3) on win32
+- typeo in im_text() when built without PANGOFT2 (thanks Stefan)
+
+1/11/04 styarted 7.10.6
+- tiny doc fixes
+- scripts now only depend on 'vips' program
+- im_open( "r" ) is now lazier ... for non-VIPS formats, we delay read until
+ the first ->generate()
+- so im_open_header() now deprecated since im_open("r") is identical
+- now looks for fftw3 as well as fftw2 ... slightly faster ffts
+
+19/10/04 started 7.10.5
+- fix to light_correct (thanks Jay)
+- edvips knows about xoffset/yoffset
+- better vips enum<->char conversions
+
+4/10/04 started 7.10.4
+- man page fixes (thanks Jay)
+- removed last csh scripts (thanks Jay)
+- scripts default VIPSHOME to $prefix (thanks Jay)
+- doc build system tidies
+- im_rank() edge padding was wrong
+- im_vips2tiff() can now embed ICC profiles
+
+22/9/04 started 7.10.3
+- mildly better im_vips2tiff()
+- *, -, +, /, % between two images now work for mixed number of bands
+- im_free() was missing a man page
+- revised documentation
+
+1/9/04 started 7.10.2
+- C++ .pc files were still set for 7.9, grr
+- im_insertplace() didn't check compatibility of images (thanks Matt)
+
+27/7/04 started 7.10.1
+- set default stack size explicitly to help platforms with a very low default
+- 16 bit RGB tiff read was broken (bug introduced in 7.9.5, thanks Haida)
+- !pangoft2 was broken, thanks Kenneth
+- win32 build fixes
+
+12/7/04 renamed as 7.10.0
+- added NOCACHE function flag ... stops nip memoising video & paint ops
+- added im_extract_bands() ... takes out many bands from an image
+- im_vips2tiff() scanline write speed up for area pipelines
+
+10/6/04 started 7.9.6
+- tiny polishing of im_ppm2vips()
+- im_blend() can now work on labq
+- boolean ops all work on float/complex images (by casting to int)
+- im_maplut() was broken for 1 band image + many band lut + >8 bit output
+- im_lintra_vec() now handles 1 band image and many band vector to make many
+ band image
+- oops, im_lintra_vec() was missing a man page
+- im_measure() can work on labq
+- im_lhisteq() uses new embed mode, _raw() version is one pixel smaller, sets
+ Xoffset/Yoffset for new origin scheme
+- generalised im_tone_build() to any image type to make im_tone_build_range()
+
+20/5/04 started 7.9.5
+- tiff output res can be a single number too
+- added im_text() to make a bitmap from a string with pango
+- im_tiff2vips() does 16 bit RGBA
+- im_binfile() was broken since 7.9.2 due to im_mapfile() change
+- im_ppm2vips() now works for 16 bit images
+- added im_copy_swap() ... copies, reversing byte order
+- im_resize_linear() was broken for some images, thanks Javi
+
+8/3/04 started 7.9.4
+- oops, config.h include missing in a few places
+- im_vips2tiff() can now write 1 bit images
+- im__find_lr/tboverlap() now exported to nip
+- better edge tile handling for tiff read/write (thanks Ruven)
+- added extend-pixels-from-edge mode to im_embed()
+- im_conv*(), im_rank(), im_stdif(), im_dilate(), im_erode() all use it to
+ expand their input, so their output now has guess borders, not black borders
+- im_fastcor() now does an im_embed( 1 ) on the output ... the zero borders
+ were very annoying before, since you would usually be searching for the
+ minimum point
+- no change to im_spcor(), since you will usually be searching for the maximum
+- better im_render() cache behaviour under heavy loads
+- im_affine() revised
+ * clip, resample and transform is now pixel-perfect for all
+ inputs (I hope)
+ * uses the new embed to make sure there are no black borders
+ from edge interpolation
+ * about 20 - 30% faster
+- policy change: Xoffset and Yoffset are now set by all operations to record
+ the position of the input origin in the output
+- im_replicate() is much faster for some cases
+- added tile and mirror flags to im_embed()
+- added im_cache() convenience function
+- better ETA for image calculation
+- im_tiff2vips() now has a "broken" option so it can read tiled tiffs made
+ with earlier versions of vips
+- on convert float to int format, now does floor() not rint() ... more
+ 'mathematical'
+- added im_rint()
+- im_sharpen() now uses a gaussian mask
+- im_convsep() more resistant to int overflow problems
+- added im_make_xy(), avoids rounding problems with the old float-based thing
+- im_profile() now makes vertical images for a vertical profile
+- added im_vips2tiff() option to set the resolution in inches not cm (thanks
+ Andrey)
+- im_binfile() is now exported
+
+6/2/04 started 7.9.3
+- added an im_init_world() to im_open(), to help old progs
+- renamed VSemaphore as im_semaphore_t
+- started using libtool library versioning
+- now uses g_module_*() in place of dlopen()
+- now uses pkg-config instead of vips-config (thanks Simon)
+- fixes to vips.h for _ADDR() with DEBUG on (thanks Konrad)
+
+10/12/03 started 7.9.2
+- patches for freebsd, thanks Lev Serebryakov
+- vips2dj knows about my colour laser printer
+- added i18n support, glib/gmodule/gthread dependency
+- im_error*() API revised to be more i18n friendly
+- List type removed, now uses g_slist
+- VBuf added, some more utility funcs pushed down from nip
+- im_thread stuff removed, now uses g_thread
+- im_lock stuff removed, now uses g_mutex
+- im_semaphore_t renamed to VSemaphore, not sure this is a good idea
+- build with --disable-threads to turn off threaded render
+- #include now pulls in most of the public API, you shouldn't
+ need other vips includes very often
+- im_close() is better at cleaning up if there's an error
+- inverse FFTs could fail for wider-than-high images with fftw
+- better im_icc_transform error messages
+- bug fix in im_render with large caches
+- im_binfile() now has an offset parameter
+- im_mapfile()/im_unmapfile() now work on IMAGE and record the length of the
+ file they mapped ... this lets VIPS successfully unmap a file if it changes
+ size while it's open
+
+20/10/03 started 7.9.1
+- threadgroups now have their own kill flag
+- im_plotmask() now does anti-aliasing
+- im_iterate() fix for operations on mmap window images (thanks Clare)
+- im_writeline() stops on kill
+- fix for im_fwfft() segv for wider-than-high real images (thanks Andrey)
+- fix for im_fwfft() to work for non-square real images (thanks Andrey)
+- can now read and write 32-bit IEEE float TIFF (Andrey Kiselev)
+- clean-ups for colour.c (Andrey Kiselev)
+- no longer lets you make an image with width|height|bands == 0 (thanks Joe)
+- im_vips2tiff(), im_vips2*jpeg*(), im_vips2png(), im_vips2ppm() could
+ sometimes fail for mmap window input images (thanks David)
+- added IM_RECT_HCENTRE(), IM_RECT_VCENTRE() macros
+
+20/8/03 JC
+- started 7.9.0
+- added im_rank_image() ... im_maxvalue() a special case of this
+- im_subtract() goes up to int earlier for better value preserving, thanks
+ Haida
+- im_rank() much faster for large windows, correct result on all platforms
+ (dratted memcpy() was causing problems before)
+- fixed problem with libMagick config if installed somewhere strange
+- fixed problem with include order in library compile
+- added --without-magick configure option
+- added im_render(), threaded background image paint
+- added im_replicate(), replicate an image horizontally and vertically
+
+31/5/03 JC
+- started 7.8.11
+- fixed a problem with relational operators and some combinations of input
+ types (bug introduced in 7.8.9), thanks Haida
+- vips-7.8 script overrides VIPSHOME environment variable
+- better im_guess_prefix
+- stupid light_correct script no longer uses /pics/tmp
+- added batch_crop script
+
+22/5/03
+- started 7.8.10
+- the JPEG writer can embed ICC profiles in output images ... although I've
+ yet to see it make any difference :-( test this carefully at some point
+- fixed a possible coredumper in jpeg write
+- jpeg read now spots truncated files
+- im_invertlut() now makes an image, not a mask ... sorry :-(
+- im_histnD() makes an n-dimensional histogram from an n-band image
+- im_col_pythagoras() patch
+- IM_NUMBER() now returns int not size_t
+- new win32 build system from Juan and friends, based on tmake
+- sample project files for MSVC added, thanks Juan
+- win32/ subdir now has the win32 build systems
+- spec/ subdir now has the spec files for building RPMs
+- dist now includes formatted documentation
+- license change: VIPS is now LGPL, nip stays GPL ... this means proprietary
+ programs can link against the vips library
+- had a report of a working VIPS build on a 64 bit system (!)
+- im_log_dmask() now includes all of the negative lobe, thanks matt
+- vips-7.8 start script now auto-relocates
+- im_spcor_raw(), im_fastcor_raw() now exported
+
+29/4/03
+- started 7.8.9
+- changes to build to help MSVC
+- oops, makedef.pl missed out function names with an initial cap, and
+ error_exit()
+- im_min() and im_max() gave random wrong results for >1 thread on >1 CPU
+ machines (bug introduced in 7.7.20), thanks Joe
+- vips.c no longer generates C++ wrappers for functions with no image argument
+ (thanks Haida)
+- im_invertlut() now wrapped by hand in VMask.cc
+- C++ docs updated
+- added im_open_header(), returns an IMAGE with just width/height/etc and no
+ data
+- ... so now "header" will print useful stuff even on truncated files
+- tiff writer knows about alpha (thanks Jenny)
+
+7/2/03
+- started 7.8.8
+- build failed with lcms turned off
+- im_spcor() could segv for 16bit images (thanks Joe)
+- im_tiff2vips() read resolution expressed as pixels/cm incorrectly
+- im_vips2tiff() tries not to write mad resolutions
+- header and im_open file type tests reordered for slight speedup
+- im_copy_set() had a broken dispatch function for xres/yres
+- im_fwfft() exploits libfftw real -> complex transform if possible for a 2x
+ speed-up (thanks Matt)
+- im_invfftr() added for complex -> real inverse transform for 2x speed-up
+ (thanks Matt)
+- im_freqflt() now uses im_invfftr() for real result and speedup
+- im_flipver() could segv on some inputs, thanks Clare
+- relational operators now work on complex
+- relational rewritten ... now fractionally slower, but 1/3 the size
+- vips2dj -1:1 produced incorrect height
+- better overlap-too-small detection in mosaicing code
+- im_system() can have NULL output
+- global balance ignores overlaps with only transparent pixels
+
+3/1/03
+- started 7.8.7
+- worked in patch from Hans Breuer (thanks!)
+ - png read/write with im_png2vips(), im_png2vips_header(),
+ im_vips2png(), im_ispng()
+ - im_errorstring() and im_col_displays() are now functions not externs
+ (helps DLLs)
+ - many include fixes to help native win32 build
+- added libMagick support, 78 file formats now loadable with
+ im_magick2vips(), im_magick2vips_header() and im_ismagick(), w00t
+- now installs vips.m4 to $prefix/share/aclocal
+- added im_icc_export_depth() ... export to device space with a specified bit
+ depth (8 or 16)
+- vips.def now rebuilt with custom rule in libsrc/Makefile.am
+- removed externs im_Type, im_BandFmt, im_Coding, im_Compression to simplify
+ DLL build
+- im_mmap() -> im__mmap(), since it's supposed to be an internal function
+- new vips-7.8.x/proj directory holds unsupported sample makefiles and
+ config.h for building with the MSC toolchain
+- new scripts batch_image_convert and batch_rubber_sheet (thanks Joe)
+- added the RPM .spec files to the main distribution
+- InitializeMagic() now passed "" rather than NULL to avoid assert() problems
+ on some libMagic versions
+
+2/12/02
+- started 7.8.6
+- now reads 8-bit RGBA tiff
+- C++ build guide fixes (thanks fsicre)
+- im_Type2char array text slightly messed up
+- global_balance is safer for complex mixed mosaics
+- removed im_lintra() fallback to im_copy() for scale == 1, offset == 0 ...
+ too confusing
+- im_tiff2vips() now reads 16-bit LAB
+- added im_Lab2LabS() and im_LabS2Lab()
+
+5/11/02
+- started 7.8.5
+- fix for mmap window of local region ... caused im_iterate() to break
+ sometimes for large images, in turn occasionally breaking
+ im_max()/im_min()/etc. (thanks Joe)
+- tiny speed up for im_rot90()/270()
+- on install on win32, add .exe suffix for links
+- vips.c knows to remove .exe suffix for linked commands
+- added im_errormsg_system() ... decode win32 error codes too
+- pagesize calcs for roving mmap windows were messed up on win32 (thanks Kirk)
+- some TODO cleanups
+- global balance broke horribly if you had filenames with spaces in (thanks
+ Clare)
+
+31/10/02
+- started 7.8.4
+- im_unmapfile() includes mixed up on mac os x
+- libtool patched for mac os x
+- vips.c sets numeric locale to "C"
+
+27/10/02
+- started 7.8.3
+- configure fixes help mac os x
+- im_guess_prefix() adds ".exe" suffix on w32 if not there
+- changed im_measure() error messages to number bands from 1
+- added func descriptor for im_read_dmask() to help nip, updated C++ API, docs
+
+21/10/02 JC
+- started 7.8.2
+- tries rand() if random() is not available
+- tries mktemp() if mkstemp() is not available
+- turns off realpath() if not available
+- added IM_DIR_SEP/IM_DIR_SEP_STR directory separator character/string
+- added IM_PATH_SEP/IM_PATH_SEP_STR path separator character/string
+- added im_path_is_absolute()
+- vips.c knows to link to vips.exe on win32
+- spot mingw* and set BINARY_OPEN
+- open images in binary too (since we now read() the header)
+
+10/10/02 JC
+- im_lintra() and im_lintra_vec() were broken for complex images :-( thanks
+ matt
+- renamed im_and() as im_andimage(), im_eor() as im_eorimage() and im_or() as
+ im_orimage() ... avoids breakage in the C++ layer
+- added im_dE00_fromLab()
+- limited release as vips-7.8.0
+
+2/10/02
+- renamed as vips-7.8, woohoo
+- revised documentation
+
+19/9/02 JC
+- started sorting out VIPS #defines ... there are now a sensible set of new
+ names (eg. NOCODING becomes IM_CODING_NONE, LAB becomes IM_TYPE_LAB)
+- define IM_NO_VIPS7_COMPAT to turn off the old names
+- added im_mmap()/im_munmap() layer for windows portability
+- removed the contents of history.h .. obsolete
+- added IM_IMAGE_ADDR() macro
+
+10/9/02 JC
+- handle errors from TIFF lib correctly
+- configure fixes for cygwin
+- CMYK TIFF write fixed
+- configure fixes for mingw
+
+5/9/02 JC
+- im_cp_desc() now copies Xoffset/Yoffset
+
+21/8/02 JC
+- started 7.7.24
+- reads CMYK TIFF
+- reads dpi from TIFFs
+- better float Xres/Yres
+
+14/8/02 JC
+- new header fields Xoffset and Yoffset ... used by functions to hint
+ the position of the origin in output images
+- support added to c++ api and to header
+- im__lrmerge(), im__tbmerge(), im__affine(), im_insert(),
+ set Xoffset/Yoffset
+- now uses , not for better suse w0rkage
+- better configure for fftw (uses libdfftw name if libfftw not found)
+
+8/8/02 JC
+- large file support with mmap() windows ... had to change
+ im_prepare_inplace() to im_prepare_to()
+
+ benchmark:
+
+ - system
+
+ hardware: 2 x 2.5GHz P4, 1GB RAM, 15k SCSI, ReiserFS
+ os: suse 8 (kernel 2.4.18)
+ compiler: gcc 2.95.3, -O2, threads turned on
+ images: fred.v, fred2.v; both 4k by 4k LABPACK (64MB)
+ images: jim.v, jim2.v; both 15k by 15k LABPACK (900MB)
+ time: smallest real of 5 runs, system idle
+ vips: 7.7.23, debug on in im_openin.c, window limit set with an
+ environment variable
+
+ - benchmarks
+
+ cpu-bound: im_sharpen fred.v fred3.v 11 1.5 20 50 1 2
+ io-bound: im_insert fred.v fred2.v fred3.v 4000 0
+ worst-case: im_rot90 fred.v fred3.v
+
+ - results
+
+ desktop:
+
+ no mmap windows mmap windows
+
+ cpu-bound real 0m3.712s real 0m3.970s
+ user 0m6.010s user 0m6.390s
+ sys 0m0.900s sys 0m1.110s
+
+ io-bound real 0m1.813s real 0m1.865s
+ user 0m0.900s user 0m0.990s
+ sys 0m1.720s sys 0m1.520s
+
+ worst-case real 0m1.344s real 0m3.039s
+ user 0m1.270s user 0m2.230s
+ sys 0m0.850s sys 0m3.050s
+
+ not quite sure why sharpen is a little slower (4%?) ... IO speed is about
+ the same though ... worst-case is having to constantly move windows about
+ (500,000 page faults, vs 10,000 for no windows)
+
+ again, with an image larger than RAM
+
+ no mmap windows mmap windows
+
+ io-bound real 2m52.759s real 2m11.172s
+ user 0m14.940s user 0m14.890s
+ sys 0m29.940s sys 0m26.560s
+
+ worst-case real 3m35.391s real 3m50.760s
+ user 0m19.850s user 0m26.600s
+ sys 0m12.650s sys 0m43.130s
+
+ mmap windows actually slightly faster in this case ... plus they stress the
+ OS less
+
+31/7/02 JC
+- added -lm for better lcms detect
+- README notes for fftw on suse8
+- im_profile() sets HISTOGRAM for output image
+- im_copy()/im_copy_set() function descriptor no longer sets PTOP ... helps
+ avoid LUT problems
+- im_subsample()/im_zoom() fall back to im_copy() for shrink/grow == 1
+- im_lintra() falls back to im_copy() for scale == 1, offset == 0
+- no longer use Type == LUT ... all just Type == HISTOGRAM now
+- im_blend() was messed up for > 1 band images :(
+
+16/7/02 JC
+- started 7.7.23
+- im_XYZ2sRGB() wasn't setting Type = sRGB
+- im_icc_import() was broken for rgb
+- im_header_string() had wrong return type in function database
+
+13/7/02 JC
+- added im_flood_blob()
+- added im_open_local_array() ... C API convenience function
+- oop, im_flood() was missing a man page
+- Type == FOURIER added to help visualisation
+- released as 7.7.22
+
+30/6/02 JC
+- JPEG, TIFF and PPM import all now set sRGB Type for RGB import
+- im_header_int(), im_header_double() and im_header_string() added to aid
+ UIs
+- now uses gettimeofday(), not time()
+- for consistency with other trig functions, im_c2amph() now returns degrees
+ not radians (ouch)
+- added im_c2rect() ... turn (amp, phase) to rectangular
+- added im_sign() ... unit vector in direction of value
+- better im_scaleps() ... old code was terrible
+- rewritten im_rotquad() ... now partial
+- im_icc_export()/_import() now do ABSOLUTE correctly
+- added im_icc_ac2rc() ... converts absolute to relative colorimetry
+
+25/6/02 JC
+- added im_copy_set(3) ... like im_copy(), but set informational header fields
+
+20/6/02 JC
+- added im_ceil(), im_floor()
+- im_Lab2LabQ was not clipping a/b range correctly
+- im_icc_export(), own ABSOLUTE mode
+- released as 7.7.21
+
+28/5/02 JC
+- im_remainderconst_vec broken for float/double
+- added Yxy colourspace
+
+16/05/02 JC
+- auug, libtool was all messed up ... redone all the autotools stuff
+- uses libtool convenience libraries to build vips in sections
+- uses config subdir for temp files and .m4 things
+- patched stupid suse config.guess
+- vips2dj patched for better raw cmyk
+- released as 7.7.20
+
+12/5/02 JC
+- im_vips2jpeg*() and im_vips2ppm() now both partial
+- started updating the C++ guide
+- had to change the location of the C++ headers :-( all C++ progs should now
+ have:
+
+ #include
+
+ this is so things can work on systems which do not have case sensitive
+ file systems
+
+- changes for Mac OS X
+ * im_system() TRUE/FALSE removed
+ * searches /*/[lib|include] to get fink libs for tiff and jpeg
+
+30/4/02 JC
+- several functions were missing IM_FN_PIO in their descriptor ... this was
+ harmless for nip/ip/C, but broke the ref counting in the C++ layer
+- im_system() now defaults "/tmp" for temp files
+- STRING input and output args were broken for C++ :-(
+- threads exit more quickly on error
+- im_min()/im_max() now partial (at last)
+- im_remainderconst()/im_remainderconst_vec() added
+- --with-dmalloc configure switch
+- vips2dj does CMYK and mono too
+- im_vips2tiff() allows any number of bands (but not the right way to
+ write CMYK, see TODO)
+
+26/4/02 JC
+- old ICC profile reader removed
+- little cms wrapped ... configure spots it, im_icc_transform() uses it to map
+ between two images
+- also im_icc_import() and im_icc_export() so you can see PCS images
+- im_icc_present() to test for existence of lib
+- README fixes
+
+4/4/02 JC
+- TODO changes
+- oops, DEBUG left on in im_invertlut()
+
+2/4/02 JC
+- im_fwfft.c/im_invfft.c now use libfftw if available ... about 5x speed up
+ and double precision
+- added FIND_FFTW autoconf macro
+- include/vips/proto.h changes
+
+26/3/02 JC
+- started 7.7.19
+
+25/3/02 JC
+- im_log_dmask() was broken (thanks matt)
+- casts between VDMask and VIMask were broken (thanks matt)
+- various error msgs improvements and tiny man page fixes
+
+13/3/02 JC
+- tb/lr merge first/last cache moved to per-call state for better sharing
+- im_remosaic() bails out faster on error and makes better error messages
+
+13/3/02 ruven
+- im_vips2tiff() pyramids stop at tilesize, not 64x64
+
+25/02/02 JC
+- im_remosaic() is smarter, and works better with im_global_balance()
+- im_affine() 2x faster
+
+14/2/02 JC
+- started 7.7.18
+- vips.m4 and libsrc/Makefile.am fixes for IRIX
+
+11/02/02 JC
+- vips/thread.h and vips/threadgroup.h were missing extern "C" for C++
+- VImage::write() now tracks dependencies, so you can write() to a partial
+ safely ... although it's not a very useful thing to do (thanks Mike)
+- new VImage::print() function for debugging
+- added im_print()
+
+22/01/02 JC
+- started 7.7.17
+
+15/01/02 JC
+- im_rect_unionrect() and im_rect_intersectrect() safer for repeated args
+- im_video_v4l() no longer perrror()s on ioctl fail for less spam
+
+03/01/02 JC
+- started 7.7.16
+- im_version_string() really does return the date as well now
+
+12/12/01 JC
+- im_guess_prefix() extra smartness for relative path names
+- VImage() no longer uses tmpnam() (thanks Paul)
+
+11/12/01 JC
+- renamed im_fexists() as im_existsf()
+
+7/12/01 JC
+- ppm man pages added (doh)
+
+28/11/01 JC
+- warnings on g++ 2.96 fixed
+
+22/11/01 JC
+- started 7.7.15
+- im_video_v4l() failed to compile on non-linux platforms
+
+7/11/01 JC
+- im_remosaic() added
+- im_*merge() are more intelligent about transparency in bizarre overlaps
+- grr! putenv() semantics change on more recent clibs ... should be safer
+ now
+
+19/10/01 JC
+- VDisplay( "display name" ) segved on unknown display :-( thanks mike
+
+26/9/01 JC
+- contrib tools get data files from share/vips/xxx area now
+- im_vipshome() renamed as im_guess_prefix(), reworked for new package layout
+- doc/ build sorted out
+- ... but of course, docs still need updating for 7.8
+
+20/9/01 JC
+- fix to im_vipshome()
+- ip2 renamed as nip
+- split to library only ... separate ip and nip packages
+- new VIPS_VERSION_* macros set from configure.in in vips/version.h.in
+- vips.m4 VIPS finder
+- reworked README, doc/README and TODO
+- now installs to /usr/local/ by default
+- fmask4th.c was including varargs.h ... d'oh
+- include area reorganised: everything inside now ... hopefully the
+ only user-visible change is that all plain C progs need to change:
+
+ #include
+
+ to:
+
+ #include
+
+ the C++ API should be unaltered
+
+21/8/01 ruven
+- im_setupout() was missing some #includes
+
+20/8/01 JC
+- started 7.7.14
+
+15/8/01 JC
+- added libxml dependency for ip2
+
+27/7/01 JC
+- im_conv(), im_convf(), im_convsep(), im_convsepf() now reject masks with
+ scale == 0
+
+26/7/01 JC
+- started 7.7.12
+
+25/7/01 JC
+- started 7.7.11
+- oop, im_histeq() and im_tonemap() also missed
+- better error messages from im_run_command()
+
+23/7/01 JC
+- started 7.7.10
+- im_sharpen() failed due to change in im_band_extract() offset
+
+20/7/01 JC
+- started 7.7.9
+
+4/7/01 JC
+- im_open(,"w") open() delayed until im_setupout(), very slightly safer
+- updated im_open() man page
+- im_tiff2vips() now embeds index in filename ... and it's page number (from
+ 0), not subsample factor
+- finally bit the bullet ... im_extract()/im_extract_band() now number from
+ zero (sorry!)
+- and im_lrmosaic()/im_tbmosaic() bandno param too
+
+29/6/01 JC
+- im_region_free() now frees immediately
+
+27/6/01 JC
+- im_vips2tiff() man page updated for deflate, 2 years late
+
+22/6/01 JC
+- oops, limit wrong on im_rank()
+
+21/6/01 JC
+- better post_install for --prefix outside VIPS's tree
+- -ltiff needs -lm in acinclude.m4 ... fixes configure on redhat 7.x
+
+13/6/01 JC
+- started 7.7.8
+
+6/6/01 JC
+- im_invertlut() added
+
+31/5/01 JC
+- im_colour_temperature, im_XYZ2Lab_temp, im_Lab2XYZ_temp added
+- ... colour temp stuff needs sorting out properly
+
+25/5/01 JC
+- added vips-config script, cf. gtk-config
+- --without-threads option added
+- did a bit of work on the C++ API docs
+
+24/5/01 JC
+- added im_tiff2vips_header(), im_jpeg2vips_header() and im_ppm2vips_header()
+- header uses these to print fields quickly
+- switched to config.h
+- configure.in rewritten ... much nicer, fewer options, more automatic
+
+17/5/01 JC
+- im_matinv() didn't free stuff correctly on singular matrix
+
+16/5/01 JC
+- vips2dj now knows about 5000ps printers
+- allow RW mode for non-native VIPS image files, for 8 bit images
+
+2/5/01 JC
+- started 7.7.7
+
+1/5/01 JC
+- im_addgnoise() did not work for >1 band images
+
+23/4/01 JC
+- configure options to remove support for JPEG and TIFF ... helpful for a no-
+ dependencies build
+
+20/4/01 JC
+- im_(v)snprintf() added
+- all sprintf()s removed
+
+15/4/01 JC
+- im_affine() had a rounding problem
+
+11/4/01 JC
+- tiny mosaicing bug fixed in im__lrcalcon
+- started 7.7.6
+
+21/3/01 JC
+- new iblend code in im_tbmerge() was typo-d
+- mosaic1 was broken by affine too
+
+20/3/01 JC
+- im_image() failed for FMTUCHAR
+
+12/3/01 JC
+- started 7.7.5
+- im_sharpen() uses seperable convolution for big speed up
+- new "Print" menu
+
+11/3/01 JC
+- REALVEC renamed as DOUBLEVEC
+- added IMAGEVEC
+- added IM_INPUT_IMAGEVEC
+- gbandjoin now has function description
+- new function im_maxvalue()
+- im_compass()/im_lindetect() reimplemented with im_conv()/im_maxvalue(),
+ about 15% faster, works for any type, partial
+- im_gradient() reimplemented with im_conv()/im_abs()/im_add(), about 30%
+ slower, works for any type, partial
+
+10/3/01 JC
+- new function, im_clip2fmt() converts between any image formats ...
+ slightly faster than the old im_clip()
+- legacy im_clip2us() etc. functions now just call this
+
+9/3/01 JC
+- im_conv() rewritten, simpler, about 10% faster
+- im_convsep() rewritten, now does any non-complex type, partial, 20% faster
+- new functions: im_convf(), im_convsepf() for DOUBLEMASK
+- raw versions of each
+- legacy convolvers (eg. im_convbi()) removed
+
+8/3/01 JC
+- new function im_blend()
+- new function im_lab_morph()
+- speed up to im_ifthenelse()
+- speed up to im_*merge() (uses integer arithmetic for integer blends)
+
+4/3/01 JC
+- tiny speed ups to im_histgr()
+- speed ups to im_maplut()
+
+3/3/01 JC
+- new functions: im_histnorm(), im_histcum()
+- im_histeq() more general
+- im_vipshome() --- better behaviour for relative paths
+
+2/3/01 JC
+- new video package
+- im_video_v4l1() (video for linux) added
+- configure.in switches to turn v4l1 on and off
+
+1/3/01 JC
+- new im_histspec() implementation ... more general, bugs removed
+
+14/2/01 JC
+- better vips2dj usage message
+
+13/2/01 JC
+- im_image_sanity() added, called in various places in iofuncs
+
+9/2/01 JC
+- added 'check' and 'name' class member stuff to ip from ip_gtk2
+- new "Plot" menu
+- new "Overlay" menu
+- more stuff in _stdenv/_list ... curried forms of head/tail etc.
+
+7/2/01 JC
+- started 7.7.4
+- vips2dj and vdump now use im_vipshome()
+
+5/2/01 JC
+- new im_vipshome() function
+- min()/max() macros renamed as MIN()/MAX()
+- new im_load_plugins() function
+- vips.exe and ip now load $VIPSHOME/lib plugins at startup
+
+2/2/01 JC
+- mosaicing functions now have an extra max blend width parameter
+
+30/1/01 JC
+- fixed tbmerge no overlap detect
+
+13/12/00 JC
+- started 7.7.3
+
+30/12/00 JC
+- vips.h fixes for cygwin/wingdi conflict
+
+27/11/00 JC
+- added im_vips2ppm(), im_open() imports and exports it
+- fixed nasty implicit output conversion problem for PIO dispatch() calls
+
+21/11/00 JC
+- added im_ppm2vips()
+
+16/11/00 JC
+- configure.in fixes ... jpeg found correctly now
+- searches for libz as well
+
+16/11/00 JC
+- started 7.7.2
+
+5/11/00 JC
+- speed up to lab2labq
+
+19/10/00 JC
+- started 7.7.1
+
+13/1/00 JC
+- oops, im_open() was missing an 'else' in jpeg/tiff load
+
+5/8/00 JC
+- im_vips2tiff() now has mode string embedded in output filename
+- im_vips2jpeg() now has qfac in output filename
+- im_open() understands this
+
+11/7/00 JC
+- new im_image() function ... wraps a VIPS image around a memory buffer
+- C++ layer changes:
+ * now use #include
+ * error renamed as VError
+ * new VMask() constructors
+ * new VImage() constructor
+ * new VImage::data() access member
+ * more operator equivalences: <, >, <=, >=, ==, !=, &, |, ^, %
+
+17/6/00 JC
+- more consts added to vips protos
+
+10/5/00 JC
+- minor configure.in changes to help solaris
+- removed _TIFFmalloc() and _TIFFfree() calls
+
+9/3/00 JC
+- fixed rounding problem in generate grid
+
+8/3/00 JC
+- fixup to im_system() temp dir
+
+7/3/00 JC
+- added im_system()
+- small tidies
+
+1/3/00 JC
+- better plugin test in configure.in
+
+26/2/00 JC
+- fixes to Makefile.am in ip/src* and configure.in, to help ip find the right
+ gtk includes on systems with more than one gtk-xxx installed
+
+21/2/00 JC
+- now builds ip and ip_gtk2
+
+16/2/00 JC
+- configure.in fixes for xil and some TIFF/JPEG strangeness
+
+15/2/00 JC
+- im_global_balancef() was broken! d'oh
+- note in README about enabling video cards
+
+10/2/00 JC
+- configure now searches for xil ... FIND_XIL macro
+- im_zoom() spots integer overflow
+- better shape set on region drag end in ip
+- better zoom-too-far handling in ip
+
+13/1/00 JC
+- fixes to configure etc. to help cygwin
+- jpeg is now searched for too ... FIND_JPEG macro
+
+10/1/00 JC
+- global_balance() now uses new affine() atuff
+
+27/12/99 JC
+- mosaic1 stuff now uses new affine() funcs
+
+21/12/99 JC
+- added Joe's docs
+- im_LabS2LabQ() rounding on a/b slightly broken for a/b == 0
+
+20/12/99 JC
+- new function: im_affine()
+- similarity*() now in terms of affine()
+- tests for error return in reduce.c from maplut
+- small clean-ups
+
+15/12/99
+- im_version() added, new iofuncs package for it
+- ip did not call zero-input-arg vips functions
+- vips.c did not like zero-input-arg functions
+
+6/12/99 JC
+- Sobel filter was a bit broken
+
+3/12/99 JC
+- menu reorganisation
+- generate gauss mask dialog
+
+2/12/99 JC
+- reworked text file IO, better error messages
+
+1/12/99 JC
+- reworked .iprc filename stuff, cleaner
+
+30/11/99 JC
+- better menu set switcher in calc preferences
+- ip now thinks it's 7.7
+- did a spellcheck on the ip guide
+
+29/11/99 JC
+- 7.7 started!
+- srgb D65->D50 converter
+- Negate added to arith
+- find similar pixel value dialog
+- find similar colour dialog
+- paste into background dialog
+
+19/11/99 JC
+- adjust labq was mising
+- shrink image defaulted to /2 not /1
+- sharpdropshadow broken
+- Rotate.* broken
+- vips-7.6.3 release
+
+18/11/99 JC
+- ip didn't report space free on >2GB filesystems correctly
+- ip did not link statically against libXpm on solaris7
+
+17/11/99 JC
+- im_histplot() failed for all 0's histogram
+- new profile_image dialog
+- man pages for im_sRGB2XYZ/im_XYZ2sRGB were broken
+- new colourize image dialog
+- new shrink image image dialog
+- new expand image image dialog
+- better doc Makefiles
+
+16/11/99 JC
+- more menu reorganising
+- new image_to_mask/mask_to_image buttons
+- new match_two_images dialog
+- new measure_colour_chart dialog
+
+15/11/99 JC
+- new custom LABQ sharpen in Image menu
+- configure support for SGI video (thanks Ruven)
+- menu fiddling in ip
+- new "resize canvas" menu item
+- im_insert_noexpand() added, no docs tho'
+
+11/11/99 JC
+- new ip menu item: Image=>Adjust white/black/saturation of LabQ
+- fixed bug in decompose complex number
+- browse-icons now ignores errors
+- better error msg for "12 12" etc cases
+
+10/11/99 JC
+- open hi-res gives proper error msg if no file found
+- made file-select boxes a bit more compact and clearer
+- updated configure.in for vips-examples-7.6
+
+9/11/99 JC
+- new column start point moved
+- vdump now defaults to subsample 1, portrait
+- navigation boxes were broken
+- no longer shrink-to-fit if loading as high res
+- better positioning of zoom windows
+- removed some old cruft
+
+8/11/99 JC
+- ooops, im_remainder() got lost somehow
+- refguide converted to latex and updated
+- cppguide updated
+
+5/11/99 JC
+- libguide converted to latex and updated
+
+4/11/99 JC
+- ip guide now latex2htmls cleanly ... still needs updating tho'
+- cpp/app guide latex2html redone
+
+2/11/99 JC
+- configure no longer adds -32 to IRIX builds for you
+- some more stuff in README
+- simple DEBUGM malloc tracking, made libsrc/iofuncs/memory.c
+- changed im_malloc() to return void *
+- removed duplicate im_malloc() proto from util.h
+- changed all malloc/free to go through im_malloc()/im_free()
+
+23/10/99 JC
+- double-click on error image now pops a load browser and an error dialog
+- add-new-column no longer scrolls to right edge of workspace
+- better scroll-to-bottom on item add
+- load ws twice does not cause 'already open' errors
+- memorise directory button in fsb
+
+18/10/99 JC
+- new FIND_TIFF/FIND_MOTIF macros for acinclude.m4
+- new ./configure switches, see ./configure --help
+- enabled static libs
+
+8/10/99
+- broke action_proc_bop() into smaller functions, stops bad code gen on
+ gcc2.95.1 (and others, prolly)
+- restored old Makefiles in doc/src/ipguide
+- vips7.6 script renamed as vips-7.6
+
+5/10/99
+- replace image was broken
+- some menu reorganisation
+- 'reload all menus' button
+
+4/10/99
+- computed regions in ip were broken
+- updated system.iprc defaults
+- new menu item: adjust white/black points
+
+2/10/99
+- browse icons was broken
+- greyscale 16-bit tiled tiff was broken
+- extra mutex locks for TIFF*() in im_tiff2vips()
+
+1/10/99
+- some automake probs fixed
+- squished two ip bugs
+
+30/9/99
+- fixed problem with pthreads, now works on suse6.2 as well
+- new API stuff for threaded evaluation with im_threadgroup_t
+- new public interface provide platform independent threads/locks/semaphores
+- no error box if you zoom out too far now
+
+26/9/99
+- lr/tb merge blend was not quite right ... should be smoother now
+- histplot broken for float images
+
+24/9/99
+- better mono->labq converter
+- more portable ispoweroftwo detect for freq filter stuff
+
+23/9/99
+- better graphics expose handling
+
+17/9/99
+- >/< stuff in ip was a bit mixed up
+- ink preview fixed for mono images
+- help popup fixed
+
+15/9/99
+- linedetect and sobel filters for ip, thnx Kirk
+
+14/9/99
+- Find_histogram was broken
+- im_profile() man pages was broken
+- ooops, ip had old set of macros
+
+10/9/99
+- im_and/im_or/im_eor now work for any integer type
+
+Summer hols: (2nd half August '99)
+- initial heap block larger to avoid start gcs
+- def slicer fixed
+- larger max heap
+- toolkits with initial '_' hidden by default
+- custom recomb
+- dialog.def removed
+- ... other menu fixes
+- generate grid menu
+- im_remainder() added
+- new cursor change code, hglass rotates during comp!
+- dialog.c handles cursor changes better
+- rubber band in paintbox displays
+- mag widget stays on right!
+- undo/redo single pixel paint ops
+- heap size control from prefs
+- cancel for reductions as well as for image calc
+- browse stuff reworked, no more .icon.v files
+- save stops you overwriting open .v files
+- better animate_countdown() handling
+- better resize behaviour for bars added to images
+- better code generation, bug fixed in state tracking
+- auto recover from crash
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/README.md b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/README.md
new file mode 100644
index 0000000..7546725
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/README.md
@@ -0,0 +1,308 @@
+# libvips : an image processing library
+
+[![CI](https://github.com/libvips/libvips/workflows/CI/badge.svg)](https://github.com/libvips/libvips/actions)
+[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/libvips.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=2&q=proj:libvips)
+[![Coverity Status](https://scan.coverity.com/projects/6503/badge.svg)](https://scan.coverity.com/projects/jcupitt-libvips)
+[![Gitter](https://badges.gitter.im/libvips/devchat.svg)](https://gitter.im/libvips/devchat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
+
+# Introduction
+
+libvips is a [demand-driven, horizontally
+threaded](https://github.com/libvips/libvips/wiki/Why-is-libvips-quick)
+image processing library. Compared to similar
+libraries, [libvips runs quickly and uses little
+memory](https://github.com/libvips/libvips/wiki/Speed-and-memory-use).
+libvips is licensed under the [LGPL
+2.1+](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html).
+
+It has around [300
+operations](https://libvips.github.io/libvips/API/current/func-list.html)
+covering arithmetic, histograms, convolution, morphological
+operations, frequency filtering, colour, resampling,
+statistics and others. It supports a large range of [numeric
+types](https://libvips.github.io/libvips/API/current/VipsImage.html#VipsBandFormat),
+from 8-bit int to 128-bit complex. Images can have any number of bands.
+It supports a good range of image formats, including JPEG, JPEG2000, JPEG-XL,
+TIFF, PNG, WebP, HEIC, AVIF, FITS, Matlab, OpenEXR, PDF, SVG, HDR, PPM / PGM /
+PFM, CSV, GIF, Analyze, NIfTI, DeepZoom, and OpenSlide. It can also load
+images via ImageMagick or GraphicsMagick, letting it work with formats
+like DICOM.
+
+It comes with bindings for
+[C](https://libvips.github.io/libvips/API/current/using-from-c.html),
+[C++](https://libvips.github.io/libvips/API/current/using-from-cpp.html),
+and the
+[command-line](https://libvips.github.io/libvips/API/current/using-cli.html).
+Full bindings are available for :
+
+| Language | Binding |
+|---|---|
+| Ruby | [ruby-vips](https://rubygems.org/gems/ruby-vips) |
+| Python | [pyvips](https://pypi.python.org/pypi/pyvips) |
+| PHP | [php-vips](https://github.com/libvips/php-vips) |
+| C# / .NET | [NetVips](https://www.nuget.org/packages/NetVips) |
+| Go | [govips](https://github.com/davidbyttow/govips) |
+| Lua | [lua-vips](https://github.com/libvips/lua-vips) |
+| Crystal | [crystal-vips](https://github.com/naqvis/crystal-vips) |
+
+libvips is used as an image processing engine by:
+
+| |
+|---|
+| [sharp (on node.js)](https://www.npmjs.org/package/sharp) |
+| [bimg](https://github.com/h2non/bimg) |
+| [sharp for Go](https://github.com/DAddYE/vips) |
+| [Ruby on Rails](https://edgeguides.rubyonrails.org/active_storage_overview.html) |
+| [carrierwave-vips](https://github.com/eltiare/carrierwave-vips) |
+| [mediawiki](https://www.mediawiki.org/wiki/Extension:VipsScaler) |
+| [PhotoFlow](https://github.com/aferrero2707/PhotoFlow) |
+
+and others. The official libvips GUI is
+[nip2](https://github.com/libvips/nip2), a strange combination of a
+spreadsheet and a photo editor.
+
+# Install
+
+There are packages for most Unix-like operating systems, including
+macOS. Check your package manager.
+
+There are binaries for Windows in
+[releases](https://github.com/libvips/libvips/releases).
+
+The [libvips website](https://libvips.github.io/libvips) has [detailed
+install notes](https://libvips.github.io/libvips/install.html).
+
+# Building from source
+
+libvips uses the [Meson build system](https://mesonbuild.com), version 0.56
+or later. Meson can use [`ninja`](https://ninja-build.org), Visual Studio or
+XCode as a backend, so you'll also need one of them.
+
+libvips must have `build-essential`, `pkg-config`, `libglib2.0-dev`,
+`libexpat1-dev`. See the **Dependencies** section below for a full list
+of the libvips optional dependencies.
+
+## Cheatsheet
+
+```
+cd libvips-x.y.x
+meson setup build-dir --prefix=/aaa/bbb/ccc
+cd build-dir
+meson compile
+meson test
+meson install
+```
+
+Check the output of `meson setup` carefully and make sure it found everything
+you wanted it to find. Add arguments to `meson setup` to change the build
+configuration.
+
+- Add flags like `-Dnsgif=false` to turn libvips options on and off, see
+ `meson_options.txt` for a list of all the build options libvips supports.
+
+- Add flags like `-Dmagick=disable` to turn libvips dependencies on and off,
+ see `meson_options.txt` and the list below for a summary of all the libvips
+ dependencies.
+
+- Meson will do a debug build by default. Add `--buildtype=release` for a
+ release (optimised) build.
+
+- You might need to add `--libdir=lib` on Debian if you don't want the arch
+ name in the library path.
+
+- Add `--default-library=static` for a static build.
+
+- Use eg. `CC=clang CXX=clang++ meson setup ...` to change compiler.
+
+- You can have many `build-dir`, pick whatever names you like, for example
+ one for release and one for debug.
+
+There's a more comprehensive test suite you can run once libvips has been
+installed. Use `pytest` in the libvips base directory.
+
+## Optional dependencies
+
+If suitable versions are found, libvips will add support for the following
+libraries automatically. Packages are generally found with `pkg-config`,
+so make sure that is working.
+
+### libjpeg
+
+The IJG JPEG library. Use the `-turbo` version if you can.
+
+### libexif
+
+If available, libvips adds support for EXIF metadata in JPEG files.
+
+### librsvg
+
+The usual SVG loader. If this is not present, vips will try to load SVGs
+via imagemagick instead.
+
+### PDFium
+
+If present, libvips will attempt to load PDFs with PDFium. Download the
+prebuilt pdfium binary from:
+
+ https://github.com/bblanchon/pdfium-binaries
+
+Untar to the libvips install prefix, for example:
+
+ cd ~/vips
+ tar xf ~/pdfium-linux.tgz
+
+Create a `pdfium.pc` like this (update the version number):
+
+ VIPSHOME=/home/john/vips
+ cat > $VIPSHOME/lib/pkgconfig/pdfium.pc << EOF
+ prefix=$VIPSHOME
+ exec_prefix=\${prefix}
+ libdir=\${exec_prefix}/lib
+ includedir=\${prefix}/include
+ Name: pdfium
+ Description: pdfium
+ Version: 4290
+ Requires:
+ Libs: -L\${libdir} -lpdfium
+ Cflags: -I\${includedir}
+ EOF
+
+If PDFium is not detected, libvips will look for `poppler-glib` instead.
+
+### poppler-glib
+
+The Poppler PDF renderer, with a glib API. If this is not present, vips
+will try to load PDFs via imagemagick.
+
+### cgif
+
+If available, libvips will save GIFs with
+[cgif](https://github.com/dloebl/cgif). If this is not present, vips will
+try to save gifs via imagemagick instead.
+
+### libgsf-1
+
+If available, libvips adds support for creating image pyramids with `dzsave`.
+
+### libtiff
+
+The TIFF library. It needs to be built with support for JPEG and
+ZIP compression. 3.4b037 and later are known to be OK.
+
+### fftw3
+
+If libvips finds this library, it uses it for fourier transforms.
+
+### lcms2
+
+If present, `vips_icc_import()`, `vips_icc_export()` and `vips_icc_transform()`
+can be used to manipulate images with ICC profiles.
+
+### libspng
+
+If present, libvips will load and save PNG files using libspng. If not, it
+will look for the standard libpng package.
+
+### libimagequant, quantizr
+
+If one of these quantisation packages is present, libvips can write 8-bit
+palette-ised PNGs and GIFs.
+
+### ImageMagick, or optionally GraphicsMagick
+
+If available, libvips adds support for loading and saving all
+libMagick-supported image file types. You can enable and disable load and save
+separately.
+
+Imagemagick 6.9+ needs to have been built with `--with-modules`. Most packaged
+IMs are, I think.
+
+If you are going to be using libvips with untrusted images, perhaps in a
+web server, for example, you should consider the security implications of
+enabling a package with such a large attack surface.
+
+### pangocairo
+
+If available, libvips adds support for text rendering. You need the
+package pangocairo in `pkg-config --list-all`.
+
+### orc-0.4
+
+If available, vips will accelerate some operations with this run-time
+compiler.
+
+### matio
+
+If available, vips can load images from Matlab save files.
+
+### cfitsio
+
+If available, vips can load FITS images.
+
+### libwebp
+
+If available, vips can load and save WebP images.
+
+### libniftiio
+
+If available, vips can load and save NIfTI images.
+
+### OpenEXR
+
+If available, libvips will directly read (but not write, sadly)
+OpenEXR images.
+
+### OpenJPEG
+
+If available, libvips will read and write JPEG2000 images.
+
+### libjxl
+
+If available, libvips will read and write JPEG-XL images.
+
+### OpenSlide
+
+If available, libvips can load OpenSlide-supported virtual slide
+files: Aperio, Hamamatsu, Leica, MIRAX, Sakura, Trestle, and Ventana.
+
+### libheif
+
+If available, libvips can load and save HEIC and AVIF images. Your libheif (in
+turn) needs to be built with the correct decoders and encoders. You can check
+with eg.:
+
+```
+$ pkg-config libheif --print-variables
+builtin_avif_decoder
+builtin_avif_encoder
+builtin_h265_decoder
+builtin_h265_encoder
+exec_prefix
+includedir
+libdir
+pcfiledir
+prefix
+```
+
+# Contributors
+
+### Code Contributors
+
+This project exists thanks to all the people who contribute.
+
+
+
+### Organizations
+
+Support this project with your organization. Your logo will show up here with a link to your website.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libaom.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libaom.dll
new file mode 100644
index 0000000..e0befa2
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libaom.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libc++.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libc++.dll
new file mode 100644
index 0000000..00704a8
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libc++.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libcairo-2.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libcairo-2.dll
new file mode 100644
index 0000000..5e8ec84
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libcairo-2.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libcgif-0.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libcgif-0.dll
new file mode 100644
index 0000000..1d6febd
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libcgif-0.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libexif-12.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libexif-12.dll
new file mode 100644
index 0000000..2f3a292
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libexif-12.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libexpat-1.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libexpat-1.dll
new file mode 100644
index 0000000..1f39229
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libexpat-1.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libffi-8.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libffi-8.dll
new file mode 100644
index 0000000..43b2d22
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libffi-8.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libfontconfig-1.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libfontconfig-1.dll
new file mode 100644
index 0000000..b61da55
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libfontconfig-1.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libfreetype-6.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libfreetype-6.dll
new file mode 100644
index 0000000..928183d
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libfreetype-6.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libfribidi-0.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libfribidi-0.dll
new file mode 100644
index 0000000..3a73e05
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libfribidi-0.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgdk_pixbuf-2.0-0.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgdk_pixbuf-2.0-0.dll
new file mode 100644
index 0000000..37b6f79
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgdk_pixbuf-2.0-0.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgio-2.0-0.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgio-2.0-0.dll
new file mode 100644
index 0000000..0fb44ea
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgio-2.0-0.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libglib-2.0-0.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libglib-2.0-0.dll
new file mode 100644
index 0000000..608ed6b
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libglib-2.0-0.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgmodule-2.0-0.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgmodule-2.0-0.dll
new file mode 100644
index 0000000..5000625
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgmodule-2.0-0.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgobject-2.0-0.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgobject-2.0-0.dll
new file mode 100644
index 0000000..ffd3a11
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgobject-2.0-0.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgsf-1-114.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgsf-1-114.dll
new file mode 100644
index 0000000..2813adb
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libgsf-1-114.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libharfbuzz-0.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libharfbuzz-0.dll
new file mode 100644
index 0000000..4fd6c1c
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libharfbuzz-0.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libheif-1.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libheif-1.dll
new file mode 100644
index 0000000..c8d5a14
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libheif-1.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libimagequant.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libimagequant.dll
new file mode 100644
index 0000000..d17600b
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libimagequant.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libjpeg-62.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libjpeg-62.dll
new file mode 100644
index 0000000..007476f
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libjpeg-62.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/liblcms2-2.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/liblcms2-2.dll
new file mode 100644
index 0000000..d86e252
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/liblcms2-2.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/liborc-0.4-0.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/liborc-0.4-0.dll
new file mode 100644
index 0000000..0f9a425
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/liborc-0.4-0.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpango-1.0-0.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpango-1.0-0.dll
new file mode 100644
index 0000000..4902e77
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpango-1.0-0.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpangocairo-1.0-0.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpangocairo-1.0-0.dll
new file mode 100644
index 0000000..ad3c9de
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpangocairo-1.0-0.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpangoft2-1.0-0.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpangoft2-1.0-0.dll
new file mode 100644
index 0000000..305f5d7
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpangoft2-1.0-0.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpixman-1-0.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpixman-1-0.dll
new file mode 100644
index 0000000..fd1f6d9
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpixman-1-0.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpng16-16.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpng16-16.dll
new file mode 100644
index 0000000..4b4575c
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libpng16-16.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/librsvg-2-2.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/librsvg-2-2.dll
new file mode 100644
index 0000000..0589742
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/librsvg-2-2.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libspng-0.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libspng-0.dll
new file mode 100644
index 0000000..0d85493
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libspng-0.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libtiff-5.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libtiff-5.dll
new file mode 100644
index 0000000..9204a3f
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libtiff-5.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libunwind.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libunwind.dll
new file mode 100644
index 0000000..4187e9f
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libunwind.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libvips-42.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libvips-42.dll
new file mode 100644
index 0000000..9e45b6a
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libvips-42.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libvips-cpp-42.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libvips-cpp-42.dll
new file mode 100644
index 0000000..02f6b6c
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libvips-cpp-42.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libwebp-7.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libwebp-7.dll
new file mode 100644
index 0000000..09315e0
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libwebp-7.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libwebpdemux-2.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libwebpdemux-2.dll
new file mode 100644
index 0000000..7c4e94f
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libwebpdemux-2.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libwebpmux-3.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libwebpmux-3.dll
new file mode 100644
index 0000000..3bf1dae
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libwebpmux-3.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libxml2-2.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libxml2-2.dll
new file mode 100644
index 0000000..65a8faa
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libxml2-2.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libz1.dll b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libz1.dll
new file mode 100644
index 0000000..7a1cd01
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/libz1.dll differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/vips.exe b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/vips.exe
new file mode 100644
index 0000000..882a509
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/vips.exe differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/vipsedit.exe b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/vipsedit.exe
new file mode 100644
index 0000000..41fdf14
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/vipsedit.exe differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/vipsheader.exe b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/vipsheader.exe
new file mode 100644
index 0000000..915db14
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/vipsheader.exe differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/vipsthumbnail.exe b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/vipsthumbnail.exe
new file mode 100644
index 0000000..ed78a0e
Binary files /dev/null and b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/bin/vipsthumbnail.exe differ
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/10-hinting-slight.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/10-hinting-slight.conf
new file mode 100644
index 0000000..96a81fb
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/10-hinting-slight.conf
@@ -0,0 +1,15 @@
+
+
+
+ Set hintslight to hintstyle
+
+
+
+ hintslight
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/10-scale-bitmap-fonts.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/10-scale-bitmap-fonts.conf
new file mode 100644
index 0000000..0c3a2ef
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/10-scale-bitmap-fonts.conf
@@ -0,0 +1,83 @@
+
+
+
+ Bitmap scaling
+
+
+
+ false
+
+
+
+ pixelsize
+ pixelsize
+
+
+
+
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+
+
+ pixelsizefixupfactor
+ 1.2
+
+
+ pixelsizefixupfactor
+ 0.8
+
+
+
+
+
+
+ true
+
+
+ 1.0
+
+
+
+
+
+ false
+
+
+ 1.0
+
+
+
+ matrix
+
+ pixelsizefixupfactor 0
+ 0 pixelsizefixupfactor
+
+
+
+
+
+ size
+ pixelsizefixupfactor
+
+
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/10-sub-pixel-rgb.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/10-sub-pixel-rgb.conf
new file mode 100644
index 0000000..a87470a
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/10-sub-pixel-rgb.conf
@@ -0,0 +1,15 @@
+
+
+
+ Enable sub-pixel rendering with the RGB stripes layout
+
+
+
+ rgb
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/10-yes-antialias.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/10-yes-antialias.conf
new file mode 100644
index 0000000..4451f6e
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/10-yes-antialias.conf
@@ -0,0 +1,8 @@
+
+
+
+ Enable antialiasing
+
+ true
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/11-lcdfilter-default.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/11-lcdfilter-default.conf
new file mode 100644
index 0000000..6025597
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/11-lcdfilter-default.conf
@@ -0,0 +1,17 @@
+
+
+
+ Use lcddefault as default for LCD filter
+
+
+
+
+ lcddefault
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/20-unhint-small-vera.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/20-unhint-small-vera.conf
new file mode 100644
index 0000000..e4e9c33
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/20-unhint-small-vera.conf
@@ -0,0 +1,49 @@
+
+
+
+ Disable hinting for Bitstream Vera fonts when the size is less than 8ppem
+
+
+
+
+ Bitstream Vera Sans
+
+
+ 7.5
+
+
+ false
+
+
+
+
+
+ Bitstream Vera Serif
+
+
+ 7.5
+
+
+ false
+
+
+
+
+
+ Bitstream Vera Sans Mono
+
+
+ 7.5
+
+
+ false
+
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/30-metric-aliases.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/30-metric-aliases.conf
new file mode 100644
index 0000000..7216b4e
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/30-metric-aliases.conf
@@ -0,0 +1,637 @@
+
+
+
+ Set substitutions for similar/metric-compatible families
+
+
+
+
+
+
+
+ Nimbus Sans L
+
+ Helvetica
+
+
+
+
+ Nimbus Sans
+
+ Helvetica
+
+
+
+
+ TeX Gyre Heros
+
+ Helvetica
+
+
+
+
+ Nimbus Sans Narrow
+
+ Helvetica Narrow
+
+
+
+
+ TeX Gyre Heros Cn
+
+ Helvetica Narrow
+
+
+
+
+ Nimbus Roman No9 L
+
+ Times
+
+
+
+
+ Nimbus Roman
+
+ Times
+
+
+
+
+ TeX Gyre Termes
+
+ Times
+
+
+
+
+ Nimbus Mono L
+
+ Courier
+
+
+
+
+ Nimbus Mono
+
+ Courier
+
+
+
+
+ Nimbus Mono PS
+
+ Courier
+
+
+
+
+ TeX Gyre Cursor
+
+ Courier
+
+
+
+
+ Avant Garde
+
+ ITC Avant Garde Gothic
+
+
+
+
+ URW Gothic L
+
+ ITC Avant Garde Gothic
+
+
+
+
+ URW Gothic
+
+ ITC Avant Garde Gothic
+
+
+
+
+ TeX Gyre Adventor
+
+ ITC Avant Garde Gothic
+
+
+
+
+ Bookman
+
+ ITC Bookman
+
+
+
+
+ URW Bookman L
+
+ ITC Bookman
+
+
+
+
+ Bookman URW
+
+ ITC Bookman
+
+
+
+
+ URW Bookman
+
+ ITC Bookman
+
+
+
+
+ TeX Gyre Bonum
+
+ ITC Bookman
+
+
+
+
+ Bookman Old Style
+
+ ITC Bookman
+
+
+
+
+ Zapf Chancery
+
+ ITC Zapf Chancery
+
+
+
+
+ URW Chancery L
+
+ ITC Zapf Chancery
+
+
+
+
+ Chancery URW
+
+ ITC Zapf Chancery
+
+
+
+
+ Z003
+
+ ITC Zapf Chancery
+
+
+
+
+ TeX Gyre Chorus
+
+ ITC Zapf Chancery
+
+
+
+
+ URW Palladio L
+
+ Palatino
+
+
+
+
+ Palladio URW
+
+ Palatino
+
+
+
+
+ P052
+
+ Palatino
+
+
+
+
+ TeX Gyre Pagella
+
+ Palatino
+
+
+
+
+ Palatino Linotype
+
+ Palatino
+
+
+
+
+ Century Schoolbook L
+
+ New Century Schoolbook
+
+
+
+
+ Century SchoolBook URW
+
+ New Century Schoolbook
+
+
+
+
+ C059
+
+ New Century Schoolbook
+
+
+
+
+ TeX Gyre Schola
+
+ New Century Schoolbook
+
+
+
+
+ Century Schoolbook
+
+ New Century Schoolbook
+
+
+
+
+
+ Arimo
+
+ Arial
+
+
+
+
+ Liberation Sans
+
+ Arial
+
+
+
+
+ Liberation Sans Narrow
+
+ Arial Narrow
+
+
+
+
+ Albany
+
+ Arial
+
+
+
+
+ Albany AMT
+
+ Arial
+
+
+
+
+ Tinos
+
+ Times New Roman
+
+
+
+
+ Liberation Serif
+
+ Times New Roman
+
+
+
+
+ Thorndale
+
+ Times New Roman
+
+
+
+
+ Thorndale AMT
+
+ Times New Roman
+
+
+
+
+ Cousine
+
+ Courier New
+
+
+
+
+ Liberation Mono
+
+ Courier New
+
+
+
+
+ Cumberland
+
+ Courier New
+
+
+
+
+ Cumberland AMT
+
+ Courier New
+
+
+
+
+ Gelasio
+
+ Georgia
+
+
+
+
+ Caladea
+
+ Cambria
+
+
+
+
+ Carlito
+
+ Calibri
+
+
+
+
+ SymbolNeu
+
+ Symbol
+
+
+
+
+
+
+
+ Helvetica
+
+ Arial
+
+
+
+
+ Helvetica Narrow
+
+ Arial Narrow
+
+
+
+
+ Times
+
+ Times New Roman
+
+
+
+
+ Courier
+
+ Courier New
+
+
+
+
+
+ Arial
+
+ Helvetica
+
+
+
+
+ Arial Narrow
+
+ Helvetica Narrow
+
+
+
+
+ Times New Roman
+
+ Times
+
+
+
+
+ Courier New
+
+ Courier
+
+
+
+
+
+
+
+ Helvetica
+
+ TeX Gyre Heros
+
+
+
+
+ Helvetica Narrow
+
+ TeX Gyre Heros Cn
+
+
+
+
+ Times
+
+ TeX Gyre Termes
+
+
+
+
+ Courier
+
+ TeX Gyre Cursor
+
+
+
+
+ Courier Std
+
+ Courier
+
+
+
+
+ ITC Avant Garde Gothic
+
+ TeX Gyre Adventor
+
+
+
+
+ ITC Bookman
+
+ Bookman Old Style
+ TeX Gyre Bonum
+
+
+
+
+ ITC Zapf Chancery
+
+ TeX Gyre Chorus
+
+
+
+
+ Palatino
+
+ Palatino Linotype
+ TeX Gyre Pagella
+
+
+
+
+ New Century Schoolbook
+
+ Century Schoolbook
+ TeX Gyre Schola
+
+
+
+
+
+ Arial
+
+ Arimo
+ Liberation Sans
+ Albany
+ Albany AMT
+
+
+
+
+ Arial Narrow
+
+ Liberation Sans Narrow
+
+
+
+
+ Times New Roman
+
+ Tinos
+ Liberation Serif
+ Thorndale
+ Thorndale AMT
+
+
+
+
+ Courier New
+
+ Cousine
+ Liberation Mono
+ Cumberland
+ Cumberland AMT
+
+
+
+
+ Georgia
+
+ Gelasio
+
+
+
+
+ Cambria
+
+ Caladea
+
+
+
+
+ Calibri
+
+ Carlito
+
+
+
+
+ Symbol
+
+ SymbolNeu
+
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/40-nonlatin.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/40-nonlatin.conf
new file mode 100644
index 0000000..f8d96ce
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/40-nonlatin.conf
@@ -0,0 +1,332 @@
+
+
+
+ Set substitutions for non-Latin fonts
+
+
+
+
+ Nazli
+ serif
+
+
+ Lotoos
+ serif
+
+
+ Mitra
+ serif
+
+
+ Ferdosi
+ serif
+
+
+ Badr
+ serif
+
+
+ Zar
+ serif
+
+
+ Titr
+ serif
+
+
+ Jadid
+ serif
+
+
+ Kochi Mincho
+ serif
+
+
+ AR PL SungtiL GB
+ serif
+
+
+ AR PL Mingti2L Big5
+ serif
+
+
+ MS 明朝
+ serif
+
+
+ NanumMyeongjo
+ serif
+
+
+ UnBatang
+ serif
+
+
+ Baekmuk Batang
+ serif
+
+
+ MgOpen Canonica
+ serif
+
+
+ Sazanami Mincho
+ serif
+
+
+ AR PL ZenKai Uni
+ serif
+
+
+ ZYSong18030
+ serif
+
+
+ FreeSerif
+ serif
+
+
+ SimSun
+ serif
+
+
+
+ Arshia
+ sans-serif
+
+
+ Elham
+ sans-serif
+
+
+ Farnaz
+ sans-serif
+
+
+ Nasim
+ sans-serif
+
+
+ Sina
+ sans-serif
+
+
+ Roya
+ sans-serif
+
+
+ Koodak
+ sans-serif
+
+
+ Terafik
+ sans-serif
+
+
+ Kochi Gothic
+ sans-serif
+
+
+ AR PL KaitiM GB
+ sans-serif
+
+
+ AR PL KaitiM Big5
+ sans-serif
+
+
+ MS ゴシック
+ sans-serif
+
+
+ NanumGothic
+ sans-serif
+
+
+ UnDotum
+ sans-serif
+
+
+ Baekmuk Dotum
+ sans-serif
+
+
+ MgOpen Modata
+ sans-serif
+
+
+ Sazanami Gothic
+ sans-serif
+
+
+ AR PL ShanHeiSun Uni
+ sans-serif
+
+
+ ZYSong18030
+ sans-serif
+
+
+ FreeSans
+ sans-serif
+
+
+
+ NSimSun
+ monospace
+
+
+ ZYSong18030
+ monospace
+
+
+ NanumGothicCoding
+ monospace
+
+
+ FreeMono
+ monospace
+
+
+
+
+ Homa
+ fantasy
+
+
+ Kamran
+ fantasy
+
+
+ Fantezi
+ fantasy
+
+
+ Tabassom
+ fantasy
+
+
+
+
+ IranNastaliq
+ cursive
+
+
+ Nafees Nastaleeq
+ cursive
+
+
+
+
+ Noto Sans Arabic UI
+ system-ui
+
+
+ Noto Sans Bengali UI
+ system-ui
+
+
+ Noto Sans Devanagari UI
+ system-ui
+
+
+ Noto Sans Gujarati UI
+ system-ui
+
+
+ Noto Sans Gurmukhi UI
+ system-ui
+
+
+ Noto Sans Kannada UI
+ system-ui
+
+
+ Noto Sans Khmer UI
+ system-ui
+
+
+ Noto Sans Lao UI
+ system-ui
+
+
+ Noto Sans Malayalam UI
+ system-ui
+
+
+ Noto Sans Myanmar UI
+ system-ui
+
+
+ Noto Sans Oriya UI
+ system-ui
+
+
+ Noto Sans Sinhala UI
+ system-ui
+
+
+ Noto Sans Tamil UI
+ system-ui
+
+
+ Noto Sans Telugu UI
+ system-ui
+
+
+ Noto Sans Thai UI
+ system-ui
+
+
+ Leelawadee UI
+ system-ui
+
+
+ Nirmala UI
+ system-ui
+
+
+ Yu Gothic UI
+ system-ui
+
+
+ Meiryo UI
+ system-ui
+
+
+ MS UI Gothic
+ system-ui
+
+
+ Khmer UI
+ system-ui
+
+
+ Lao UI
+ system-ui
+
+
+ Microsoft JhengHei UI
+ system-ui
+
+
+ Microsoft YaHei UI
+ system-ui
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/45-generic.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/45-generic.conf
new file mode 100644
index 0000000..5c1bd36
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/45-generic.conf
@@ -0,0 +1,136 @@
+
+
+
+ Set substitutions for emoji/math fonts
+
+
+
+
+
+
+
+ Noto Color Emoji
+ emoji
+
+
+ Apple Color Emoji
+ emoji
+
+
+ Segoe UI Emoji
+ emoji
+
+
+ Twitter Color Emoji
+ emoji
+
+
+ EmojiOne Mozilla
+ emoji
+
+
+
+ Emoji Two
+ emoji
+
+
+ JoyPixels
+ emoji
+
+
+ Emoji One
+ emoji
+
+
+
+ Noto Emoji
+ emoji
+
+
+ Android Emoji
+ emoji
+
+
+
+
+
+ emoji
+
+
+ und-zsye
+
+
+
+
+
+ und-zsye
+
+
+ emoji
+
+
+
+
+ emoji
+
+
+
+
+
+
+
+
+ XITS Math
+ math
+
+
+ STIX Two Math
+ math
+
+
+ Cambria Math
+ math
+
+
+ Latin Modern Math
+ math
+
+
+ Minion Math
+ math
+
+
+ Lucida Math
+ math
+
+
+ Asana Math
+ math
+
+
+
+
+
+ math
+
+
+ und-zmth
+
+
+
+
+
+ und-zmth
+
+
+ math
+
+
+
+
+ math
+
+
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/45-latin.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/45-latin.conf
new file mode 100644
index 0000000..86486c9
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/45-latin.conf
@@ -0,0 +1,301 @@
+
+
+
+ Set substitutions for Latin fonts
+
+
+
+
+ Bitstream Vera Serif
+ serif
+
+
+ Cambria
+ serif
+
+
+ Constantia
+ serif
+
+
+ DejaVu Serif
+ serif
+
+
+ Elephant
+ serif
+
+
+ Garamond
+ serif
+
+
+ Georgia
+ serif
+
+
+ Liberation Serif
+ serif
+
+
+ Luxi Serif
+ serif
+
+
+ MS Serif
+ serif
+
+
+ Nimbus Roman No9 L
+ serif
+
+
+ Nimbus Roman
+ serif
+
+
+ Palatino Linotype
+ serif
+
+
+ Thorndale AMT
+ serif
+
+
+ Thorndale
+ serif
+
+
+ Times New Roman
+ serif
+
+
+ Times
+ serif
+
+
+
+ Albany AMT
+ sans-serif
+
+
+ Albany
+ sans-serif
+
+
+ Arial Unicode MS
+ sans-serif
+
+
+ Arial
+ sans-serif
+
+
+ Bitstream Vera Sans
+ sans-serif
+
+
+ Britannic
+ sans-serif
+
+
+ Calibri
+ sans-serif
+
+
+ Candara
+ sans-serif
+
+
+ Century Gothic
+ sans-serif
+
+
+ Corbel
+ sans-serif
+
+
+ DejaVu Sans
+ sans-serif
+
+
+ Helvetica
+ sans-serif
+
+
+ Haettenschweiler
+ sans-serif
+
+
+ Liberation Sans
+ sans-serif
+
+
+ MS Sans Serif
+ sans-serif
+
+
+ Nimbus Sans L
+ sans-serif
+
+
+ Nimbus Sans
+ sans-serif
+
+
+ Luxi Sans
+ sans-serif
+
+
+ Tahoma
+ sans-serif
+
+
+ Trebuchet MS
+ sans-serif
+
+
+ Twentieth Century
+ sans-serif
+
+
+ Verdana
+ sans-serif
+
+
+
+ Andale Mono
+ monospace
+
+
+ Bitstream Vera Sans Mono
+ monospace
+
+
+ Consolas
+ monospace
+
+
+ Courier New
+ monospace
+
+
+ Courier
+ monospace
+
+
+ Courier Std
+ monospace
+
+
+ Cumberland AMT
+ monospace
+
+
+ Cumberland
+ monospace
+
+
+ DejaVu Sans Mono
+ monospace
+
+
+ Fixedsys
+ monospace
+
+
+ Inconsolata
+ monospace
+
+
+ Liberation Mono
+ monospace
+
+
+ Luxi Mono
+ monospace
+
+
+ Nimbus Mono L
+ monospace
+
+
+ Nimbus Mono
+ monospace
+
+
+ Nimbus Mono PS
+ monospace
+
+
+ Terminal
+ monospace
+
+
+
+ Bauhaus Std
+ fantasy
+
+
+ Cooper Std
+ fantasy
+
+
+ Copperplate Gothic Std
+ fantasy
+
+
+ Impact
+ fantasy
+
+
+
+ Comic Sans MS
+ cursive
+
+
+ ITC Zapf Chancery Std
+ cursive
+
+
+ Zapfino
+ cursive
+
+
+
+ Cantarell
+ system-ui
+
+
+ Noto Sans UI
+ system-ui
+
+
+ Segoe UI
+ system-ui
+
+
+ Segoe UI Historic
+ system-ui
+
+
+ Segoe UI Symbol
+ system-ui
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/48-spacing.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/48-spacing.conf
new file mode 100644
index 0000000..6df5c11
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/48-spacing.conf
@@ -0,0 +1,16 @@
+
+
+
+ Add mono to the family when spacing is 100
+
+
+
+ 100
+
+
+ monospace
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/49-sansserif.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/49-sansserif.conf
new file mode 100644
index 0000000..6cc3a1c
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/49-sansserif.conf
@@ -0,0 +1,22 @@
+
+
+
+ Add sans-serif to the family when no generic name
+
+
+
+ sans-serif
+
+
+ serif
+
+
+ monospace
+
+
+ sans-serif
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/50-user.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/50-user.conf
new file mode 100644
index 0000000..d019f4d
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/50-user.conf
@@ -0,0 +1,16 @@
+
+
+
+ Load per-user customization files
+
+ fontconfig/conf.d
+ fontconfig/fonts.conf
+
+ ~/.fonts.conf.d
+ ~/.fonts.conf
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/51-local.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/51-local.conf
new file mode 100644
index 0000000..82e3c1b
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/51-local.conf
@@ -0,0 +1,7 @@
+
+
+
+ Load local customization file
+
+ local.conf
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/60-generic.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/60-generic.conf
new file mode 100644
index 0000000..7831507
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/60-generic.conf
@@ -0,0 +1,64 @@
+
+
+
+ Set preferable fonts for emoji/math fonts
+
+
+
+
+
+
+
+ und-zsye
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+
+
+
+ emoji
+
+
+ Noto Color Emoji
+ Apple Color Emoji
+ Segoe UI Emoji
+ Twitter Color Emoji
+ EmojiOne Mozilla
+
+ Emoji Two
+ JoyPixels
+ Emoji One
+
+ Noto Emoji
+ Android Emoji
+
+
+
+
+
+
+ math
+
+ XITS Math
+ STIX Two Math
+ Cambria Math
+ Latin Modern Math
+ Minion Math
+ Lucida Math
+ Asana Math
+
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/60-latin.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/60-latin.conf
new file mode 100644
index 0000000..ff933af
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/60-latin.conf
@@ -0,0 +1,88 @@
+
+
+
+ Set preferable fonts for Latin
+
+ serif
+
+ Noto Serif
+ DejaVu Serif
+ Times New Roman
+ Thorndale AMT
+ Luxi Serif
+ Nimbus Roman No9 L
+ Nimbus Roman
+ Times
+
+
+
+ sans-serif
+
+ Noto Sans
+ DejaVu Sans
+ Verdana
+ Arial
+ Albany AMT
+ Luxi Sans
+ Nimbus Sans L
+ Nimbus Sans
+ Helvetica
+ Lucida Sans Unicode
+ BPG Glaho International
+ Tahoma
+
+
+
+ monospace
+
+ Noto Sans Mono
+ DejaVu Sans Mono
+ Inconsolata
+ Andale Mono
+ Courier New
+ Cumberland AMT
+ Luxi Mono
+ Nimbus Mono L
+ Nimbus Mono
+ Nimbus Mono PS
+ Courier
+
+
+
+
+ fantasy
+
+ Impact
+ Copperplate Gothic Std
+ Cooper Std
+ Bauhaus Std
+
+
+
+
+ cursive
+
+ ITC Zapf Chancery Std
+ Zapfino
+ Comic Sans MS
+
+
+
+
+ system-ui
+
+ Cantarell
+ Noto Sans UI
+ Segoe UI
+ Segoe UI Historic
+ Segoe UI Symbol
+
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/65-fonts-persian.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/65-fonts-persian.conf
new file mode 100644
index 0000000..47da1bb
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/65-fonts-persian.conf
@@ -0,0 +1,418 @@
+
+
+
+
+
+
+
+
+
+ Nesf
+ Nesf2
+
+
+ Nesf2
+ Persian_sansserif_default
+
+
+
+
+
+ Nazanin
+ Nazli
+
+
+ Lotus
+ Lotoos
+
+
+ Yaqut
+ Yaghoot
+
+
+ Yaghut
+ Yaghoot
+
+
+ Traffic
+ Terafik
+
+
+ Ferdowsi
+ Ferdosi
+
+
+ Fantezy
+ Fantezi
+
+
+
+
+
+
+
+ Jadid
+ Persian_title
+
+
+ Titr
+ Persian_title
+
+
+
+
+ Kamran
+
+ Persian_fantasy
+ Homa
+
+
+
+ Homa
+
+ Persian_fantasy
+ Kamran
+
+
+
+ Fantezi
+ Persian_fantasy
+
+
+ Tabassom
+ Persian_fantasy
+
+
+
+
+ Arshia
+ Persian_square
+
+
+ Nasim
+ Persian_square
+
+
+ Elham
+
+ Persian_square
+ Farnaz
+
+
+
+ Farnaz
+
+ Persian_square
+ Elham
+
+
+
+ Sina
+ Persian_square
+
+
+
+
+
+
+ Persian_title
+
+ Titr
+ Jadid
+ Persian_serif
+
+
+
+
+
+ Persian_fantasy
+
+ Homa
+ Kamran
+ Fantezi
+ Tabassom
+ Persian_square
+
+
+
+
+
+ Persian_square
+
+ Arshia
+ Elham
+ Farnaz
+ Nasim
+ Sina
+ Persian_serif
+
+
+
+
+
+
+
+ Elham
+
+
+ farsiweb
+
+
+
+
+
+ Homa
+
+
+ farsiweb
+
+
+
+
+
+ Koodak
+
+
+ farsiweb
+
+
+
+
+
+ Nazli
+
+
+ farsiweb
+
+
+
+
+
+ Roya
+
+
+ farsiweb
+
+
+
+
+
+ Terafik
+
+
+ farsiweb
+
+
+
+
+
+ Titr
+
+
+ farsiweb
+
+
+
+
+
+
+
+
+
+ TURNED-OFF
+
+
+ farsiweb
+
+
+
+ roman
+
+
+
+ roman
+
+
+
+
+ matrix
+ 1-0.2
+ 01
+
+
+
+
+
+ oblique
+
+
+
+
+
+
+
+
+ farsiweb
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+
+
+
+
+
+
+ serif
+
+ Nazli
+ Lotoos
+ Mitra
+ Ferdosi
+ Badr
+ Zar
+
+
+
+
+
+ sans-serif
+
+ Roya
+ Koodak
+ Terafik
+
+
+
+
+
+ monospace
+
+
+ Terafik
+
+
+
+
+
+ fantasy
+
+ Homa
+ Kamran
+ Fantezi
+ Tabassom
+
+
+
+
+
+ cursive
+
+ IranNastaliq
+ Nafees Nastaleeq
+
+
+
+
+
+
+
+
+ serif
+
+
+ 200
+
+
+ 24
+
+
+ Titr
+
+
+
+
+
+
+ sans-serif
+
+
+ 200
+
+
+ 24
+
+
+ Titr
+
+
+
+
+
+
+ Persian_sansserif_default
+
+
+ 200
+
+
+ 24
+
+
+ Titr
+
+
+
+
+
+
+
+
+ Persian_sansserif_default
+
+
+ Roya
+
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/65-nonlatin.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/65-nonlatin.conf
new file mode 100644
index 0000000..4d135b0
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/65-nonlatin.conf
@@ -0,0 +1,228 @@
+
+
+
+ Set preferable fonts for non-Latin
+
+ serif
+
+ Artsounk
+ BPG UTF8 M
+ Kinnari
+ Norasi
+ Frank Ruehl
+ Dror
+ JG LaoTimes
+ Saysettha Unicode
+ Pigiarniq
+ B Davat
+ B Compset
+ Kacst-Qr
+ Urdu Nastaliq Unicode
+ Raghindi
+ Mukti Narrow
+ malayalam
+ Sampige
+ padmaa
+ Hapax Berbère
+ MS Mincho
+ SimSun
+ PMingLiu
+ WenQuanYi Zen Hei
+ WenQuanYi Bitmap Song
+ AR PL ShanHeiSun Uni
+ AR PL New Sung
+ ZYSong18030
+ HanyiSong
+ MgOpen Canonica
+ Sazanami Mincho
+ IPAMonaMincho
+ IPAMincho
+ Kochi Mincho
+ AR PL SungtiL GB
+ AR PL Mingti2L Big5
+ AR PL Zenkai Uni
+ MS 明朝
+ ZYSong18030
+ NanumMyeongjo
+ UnBatang
+ Baekmuk Batang
+ KacstQura
+ Frank Ruehl CLM
+ Lohit Bengali
+ Lohit Gujarati
+ Lohit Hindi
+ Lohit Marathi
+ Lohit Maithili
+ Lohit Kashmiri
+ Lohit Konkani
+ Lohit Nepali
+ Lohit Sindhi
+ Lohit Punjabi
+ Lohit Tamil
+ Rachana
+ Lohit Malayalam
+ Lohit Kannada
+ Lohit Telugu
+ Lohit Oriya
+ LKLUG
+
+
+
+ sans-serif
+
+ Nachlieli
+ Lucida Sans Unicode
+ Yudit Unicode
+ Kerkis
+ ArmNet Helvetica
+ Artsounk
+ BPG UTF8 M
+ Waree
+ Loma
+ Garuda
+ Umpush
+ Saysettha Unicode
+ JG Lao Old Arial
+ GF Zemen Unicode
+ Pigiarniq
+ B Davat
+ B Compset
+ Kacst-Qr
+ Urdu Nastaliq Unicode
+ Raghindi
+ Mukti Narrow
+ malayalam
+ Sampige
+ padmaa
+ Hapax Berbère
+ MS Gothic
+ UmePlus P Gothic
+ Microsoft YaHei
+ Microsoft JhengHei
+ WenQuanYi Zen Hei
+ WenQuanYi Bitmap Song
+ AR PL ShanHeiSun Uni
+ AR PL New Sung
+ MgOpen Modata
+ VL Gothic
+ IPAMonaGothic
+ IPAGothic
+ Sazanami Gothic
+ Kochi Gothic
+ AR PL KaitiM GB
+ AR PL KaitiM Big5
+ AR PL ShanHeiSun Uni
+ AR PL SungtiL GB
+ AR PL Mingti2L Big5
+ MS ゴシック
+ ZYSong18030
+ TSCu_Paranar
+ NanumGothic
+ UnDotum
+ Baekmuk Dotum
+ Baekmuk Gulim
+ KacstQura
+ Lohit Bengali
+ Lohit Gujarati
+ Lohit Hindi
+ Lohit Marathi
+ Lohit Maithili
+ Lohit Kashmiri
+ Lohit Konkani
+ Lohit Nepali
+ Lohit Sindhi
+ Lohit Punjabi
+ Lohit Tamil
+ Meera
+ Lohit Malayalam
+ Lohit Kannada
+ Lohit Telugu
+ Lohit Oriya
+ LKLUG
+
+
+
+ monospace
+
+ Miriam Mono
+ VL Gothic
+ IPAMonaGothic
+ IPAGothic
+ Sazanami Gothic
+ Kochi Gothic
+ AR PL KaitiM GB
+ MS Gothic
+ UmePlus Gothic
+ NSimSun
+ MingLiu
+ AR PL ShanHeiSun Uni
+ AR PL New Sung Mono
+ HanyiSong
+ AR PL SungtiL GB
+ AR PL Mingti2L Big5
+ ZYSong18030
+ NanumGothicCoding
+ NanumGothic
+ UnDotum
+ Baekmuk Dotum
+ Baekmuk Gulim
+ TlwgTypo
+ TlwgTypist
+ TlwgTypewriter
+ TlwgMono
+ Hasida
+ GF Zemen Unicode
+ Hapax Berbère
+ Lohit Bengali
+ Lohit Gujarati
+ Lohit Hindi
+ Lohit Marathi
+ Lohit Maithili
+ Lohit Kashmiri
+ Lohit Konkani
+ Lohit Nepali
+ Lohit Sindhi
+ Lohit Punjabi
+ Lohit Tamil
+ Meera
+ Lohit Malayalam
+ Lohit Kannada
+ Lohit Telugu
+ Lohit Oriya
+ LKLUG
+
+
+
+
+ system-ui
+
+ Noto Sans Arabic UI
+ Noto Sans Bengali UI
+ Noto Sans Devanagari UI
+ Noto Sans Gujarati UI
+ Noto Sans Gurmukhi UI
+ Noto Sans Kannada UI
+ Noto Sans Khmer UI
+ Noto Sans Lao UI
+ Noto Sans Malayalam UI
+ Noto Sans Myanmar UI
+ Noto Sans Oriya UI
+ Noto Sans Sinhala UI
+ Noto Sans Tamil UI
+ Noto Sans Telugu UI
+ Noto Sans Thai UI
+ Leelawadee UI
+ Nirmala UI
+ Yu Gothic UI
+ Meiryo UI
+ MS UI Gothic
+ Khmer UI
+ Lao UI
+ Microsoft YaHei UI
+ Microsoft JhengHei UI
+
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/69-unifont.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/69-unifont.conf
new file mode 100644
index 0000000..02854ff
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/69-unifont.conf
@@ -0,0 +1,28 @@
+
+
+
+
+ serif
+
+ FreeSerif
+ Code2000
+ Code2001
+
+
+
+ sans-serif
+
+ FreeSans
+ Arial Unicode MS
+ Arial Unicode
+ Code2000
+ Code2001
+
+
+
+ monospace
+
+ FreeMono
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/80-delicious.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/80-delicious.conf
new file mode 100644
index 0000000..d20990c
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/80-delicious.conf
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+ Delicious
+
+
+ Heavy
+
+
+ heavy
+
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/90-synthetic.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/90-synthetic.conf
new file mode 100644
index 0000000..dfce674
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/90-synthetic.conf
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+ roman
+
+
+
+ roman
+
+
+
+
+ matrix
+ 10.2
+ 01
+
+
+
+
+
+ oblique
+
+
+
+ false
+
+
+
+
+
+
+
+
+ medium
+
+
+
+ bold
+
+
+
+ true
+
+
+
+ bold
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/README b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/README
new file mode 100644
index 0000000..75b4aee
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/conf.d/README
@@ -0,0 +1,23 @@
+conf.d/README
+
+Each file in this directory is a fontconfig configuration file. Fontconfig
+scans this directory, loading all files of the form [0-9][0-9]*.conf.
+These files are normally installed in /data/mxe/usr/x86_64-w64-mingw32.shared.posix.web/share/fontconfig/conf.avail
+and then symlinked here, allowing them to be easily installed and then
+enabled/disabled by adjusting the symlinks.
+
+The files are loaded in numeric order, the structure of the configuration
+has led to the following conventions in usage:
+
+ Files beginning with: Contain:
+
+ 00 through 09 Font directories
+ 10 through 19 system rendering defaults (AA, etc)
+ 20 through 29 font rendering options
+ 30 through 39 family substitution
+ 40 through 49 generic identification, map family->generic
+ 50 through 59 alternate config file loading
+ 60 through 69 generic aliases, map generic->family
+ 70 through 79 select font (adjust which fonts are available)
+ 80 through 89 match target="scan" (modify scanned patterns)
+ 90 through 99 font synthesis
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/fonts.conf b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/fonts.conf
new file mode 100644
index 0000000..c8fdfc2
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/etc/fonts/fonts.conf
@@ -0,0 +1,103 @@
+
+
+
+
+ Default configuration file
+
+
+
+
+
+ WINDOWSFONTDIR
+ WINDOWSUSERFONTDIR
+
+
+ fonts
+
+ ~/.fonts
+
+
+
+
+ mono
+
+
+ monospace
+
+
+
+
+
+
+ sans serif
+
+
+ sans-serif
+
+
+
+
+
+
+ sans
+
+
+ sans-serif
+
+
+
+
+
+ system ui
+
+
+ system-ui
+
+
+
+
+ conf.d
+
+
+
+ LOCAL_APPDATA_FONTCONFIG_CACHE
+ fontconfig
+
+ ~/.fontconfig
+
+
+
+
+ 30
+
+
+
+
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom.h
new file mode 100644
index 0000000..0650a11
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+/*!\defgroup aom AOM
+ * \ingroup codecs
+ * AOM is aom's newest video compression algorithm that uses motion
+ * compensated prediction, Discrete Cosine Transform (DCT) coding of the
+ * prediction error signal and context dependent entropy coding techniques
+ * based on arithmetic principles. It features:
+ * - YUV 4:2:0 image format
+ * - Macro-block based coding (16x16 luma plus two 8x8 chroma)
+ * - 1/4 (1/8) pixel accuracy motion compensated prediction
+ * - 4x4 DCT transform
+ * - 128 level linear quantizer
+ * - In loop deblocking filter
+ * - Context-based entropy coding
+ *
+ * @{
+ */
+/*!\file
+ * \brief Provides controls common to both the AOM encoder and decoder.
+ */
+#ifndef AOM_AOM_AOM_H_
+#define AOM_AOM_AOM_H_
+
+#include "aom/aom_codec.h"
+#include "aom/aom_image.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!\brief Control functions
+ *
+ * The set of macros define the control functions of AOM interface
+ * The range for common control IDs is 230-255(max).
+ */
+enum aom_com_control_id {
+ /*!\brief Codec control function to get a pointer to a reference frame
+ *
+ * av1_ref_frame_t* parameter
+ */
+ AV1_GET_REFERENCE = 230,
+
+ /*!\brief Codec control function to write a frame into a reference buffer
+ *
+ * av1_ref_frame_t* parameter
+ */
+ AV1_SET_REFERENCE = 231,
+
+ /*!\brief Codec control function to get a copy of reference frame from the
+ * decoder
+ *
+ * av1_ref_frame_t* parameter
+ */
+ AV1_COPY_REFERENCE = 232,
+
+ /*!\brief Codec control function to get a pointer to the new frame
+ *
+ * aom_image_t* parameter
+ */
+ AV1_GET_NEW_FRAME_IMAGE = 233,
+
+ /*!\brief Codec control function to copy the new frame to an external buffer
+ *
+ * aom_image_t* parameter
+ */
+ AV1_COPY_NEW_FRAME_IMAGE = 234,
+
+ /*!\brief Start point of control IDs for aom_dec_control_id.
+ * Any new common control IDs should be added above.
+ */
+ AOM_DECODER_CTRL_ID_START = 256
+ // No common control IDs should be added after AOM_DECODER_CTRL_ID_START.
+};
+
+/*!\brief AV1 specific reference frame data struct
+ *
+ * Define the data struct to access av1 reference frames.
+ */
+typedef struct av1_ref_frame {
+ int idx; /**< frame index to get (input) */
+ int use_external_ref; /**< Directly use external ref buffer(decoder only) */
+ aom_image_t img; /**< img structure to populate (output) */
+} av1_ref_frame_t;
+
+/*!\cond */
+/*!\brief aom decoder control function parameter type
+ *
+ * Defines the data type for each of AOM decoder control function requires.
+ *
+ * \note For each control ID "X", a macro-define of
+ * AOM_CTRL_X is provided. It is used at compile time to determine
+ * if the control ID is supported by the libaom library available,
+ * when the libaom version cannot be controlled.
+ */
+AOM_CTRL_USE_TYPE(AV1_GET_REFERENCE, av1_ref_frame_t *)
+#define AOM_CTRL_AV1_GET_REFERENCE
+
+AOM_CTRL_USE_TYPE(AV1_SET_REFERENCE, av1_ref_frame_t *)
+#define AOM_CTRL_AV1_SET_REFERENCE
+
+AOM_CTRL_USE_TYPE(AV1_COPY_REFERENCE, av1_ref_frame_t *)
+#define AOM_CTRL_AV1_COPY_REFERENCE
+
+AOM_CTRL_USE_TYPE(AV1_GET_NEW_FRAME_IMAGE, aom_image_t *)
+#define AOM_CTRL_AV1_GET_NEW_FRAME_IMAGE
+
+AOM_CTRL_USE_TYPE(AV1_COPY_NEW_FRAME_IMAGE, aom_image_t *)
+#define AOM_CTRL_AV1_COPY_NEW_FRAME_IMAGE
+
+/*!\endcond */
+/*! @} - end defgroup aom */
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // AOM_AOM_AOM_H_
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_codec.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_codec.h
new file mode 100644
index 0000000..49d48cf
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_codec.h
@@ -0,0 +1,573 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+///////////////////////////////////////////////////////////////////////////////
+// Internal implementation details
+///////////////////////////////////////////////////////////////////////////////
+//
+// There are two levels of interfaces used to access the AOM codec: the
+// the aom_codec_iface and the aom_codec_ctx.
+//
+// 1. aom_codec_iface_t
+// (Related files: aom/aom_codec.h, aom/src/aom_codec.c,
+// aom/internal/aom_codec_internal.h, av1/av1_cx_iface.c,
+// av1/av1_dx_iface.c)
+//
+// Used to initialize the codec context, which contains the configuration for
+// for modifying the encoder/decoder during run-time. See the other
+// documentation in this header file for more details. For the most part,
+// users will call helper functions, such as aom_codec_iface_name,
+// aom_codec_get_caps, etc., to interact with it.
+//
+// The main purpose of the aom_codec_iface_t is to provide a way to generate
+// a default codec config, find out what capabilities the implementation has,
+// and create an aom_codec_ctx_t (which is actually used to interact with the
+// codec).
+//
+// Note that the implementations for the AV1 algorithm are located in
+// av1/av1_cx_iface.c and av1/av1_dx_iface.c
+//
+//
+// 2. aom_codec_ctx_t
+// (Related files: aom/aom_codec.h, av1/av1_cx_iface.c, av1/av1_dx_iface.c,
+// aom/aomcx.h, aom/aomdx.h, aom/src/aom_encoder.c, aom/src/aom_decoder.c)
+//
+// The actual interface between user code and the codec. It stores the name
+// of the codec, a pointer back to the aom_codec_iface_t that initialized it,
+// initialization flags, a config for either encoder or the decoder, and a
+// pointer to internal data.
+//
+// The codec is configured / queried through calls to aom_codec_control,
+// which takes a control ID (listed in aomcx.h and aomdx.h) and a parameter.
+// In the case of "getter" control IDs, the parameter is modified to have
+// the requested value; in the case of "setter" control IDs, the codec's
+// configuration is changed based on the parameter. Note that a aom_codec_err_t
+// is returned, which indicates if the operation was successful or not.
+//
+// Note that for the encoder, the aom_codec_alg_priv_t points to the
+// the aom_codec_alg_priv structure in av1/av1_cx_iface.c, and for the decoder,
+// the struct in av1/av1_dx_iface.c. Variables such as AV1_COMP cpi are stored
+// here and also used in the core algorithm.
+//
+// At the end, aom_codec_destroy should be called for each initialized
+// aom_codec_ctx_t.
+
+/*!\defgroup codec Common Algorithm Interface
+ * This abstraction allows applications to easily support multiple video
+ * formats with minimal code duplication. This section describes the interface
+ * common to all codecs (both encoders and decoders).
+ * @{
+ */
+
+/*!\file
+ * \brief Describes the codec algorithm interface to applications.
+ *
+ * This file describes the interface between an application and a
+ * video codec algorithm.
+ *
+ * An application instantiates a specific codec instance by using
+ * aom_codec_dec_init() or aom_codec_enc_init() and a pointer to the
+ * algorithm's interface structure:
+ *
+ * my_app.c:
+ * extern aom_codec_iface_t my_codec;
+ * {
+ * aom_codec_ctx_t algo;
+ * int threads = 4;
+ * aom_codec_dec_cfg_t cfg = { threads, 0, 0, 1 };
+ * res = aom_codec_dec_init(&algo, &my_codec, &cfg, 0);
+ * }
+ *
+ *
+ * Once initialized, the instance is managed using other functions from
+ * the aom_codec_* family.
+ */
+#ifndef AOM_AOM_AOM_CODEC_H_
+#define AOM_AOM_AOM_CODEC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "aom/aom_image.h"
+#include "aom/aom_integer.h"
+
+/*!\brief Decorator indicating a function is deprecated */
+#ifndef AOM_DEPRECATED
+#if defined(__GNUC__) && __GNUC__
+#define AOM_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER)
+#define AOM_DEPRECATED
+#else
+#define AOM_DEPRECATED
+#endif
+#endif /* AOM_DEPRECATED */
+
+#ifndef AOM_DECLSPEC_DEPRECATED
+#if defined(__GNUC__) && __GNUC__
+#define AOM_DECLSPEC_DEPRECATED /**< \copydoc #AOM_DEPRECATED */
+#elif defined(_MSC_VER)
+/*!\brief \copydoc #AOM_DEPRECATED */
+#define AOM_DECLSPEC_DEPRECATED __declspec(deprecated)
+#else
+#define AOM_DECLSPEC_DEPRECATED /**< \copydoc #AOM_DEPRECATED */
+#endif
+#endif /* AOM_DECLSPEC_DEPRECATED */
+
+/*!\brief Decorator indicating a function is potentially unused */
+#ifdef AOM_UNUSED
+#elif defined(__GNUC__) || defined(__clang__)
+#define AOM_UNUSED __attribute__((unused))
+#else
+#define AOM_UNUSED
+#endif
+
+/*!\brief Decorator indicating that given struct/union/enum is packed */
+#ifndef ATTRIBUTE_PACKED
+#if defined(__GNUC__) && __GNUC__
+#define ATTRIBUTE_PACKED __attribute__((packed))
+#elif defined(_MSC_VER)
+#define ATTRIBUTE_PACKED
+#else
+#define ATTRIBUTE_PACKED
+#endif
+#endif /* ATTRIBUTE_PACKED */
+
+/*!\brief Current ABI version number
+ *
+ * \internal
+ * If this file is altered in any way that changes the ABI, this value
+ * must be bumped. Examples include, but are not limited to, changing
+ * types, removing or reassigning enums, adding/removing/rearranging
+ * fields to structures
+ */
+#define AOM_CODEC_ABI_VERSION (7 + AOM_IMAGE_ABI_VERSION) /**<\hideinitializer*/
+
+/*!\brief Algorithm return codes */
+typedef enum {
+ /*!\brief Operation completed without error */
+ AOM_CODEC_OK,
+
+ /*!\brief Unspecified error */
+ AOM_CODEC_ERROR,
+
+ /*!\brief Memory operation failed */
+ AOM_CODEC_MEM_ERROR,
+
+ /*!\brief ABI version mismatch */
+ AOM_CODEC_ABI_MISMATCH,
+
+ /*!\brief Algorithm does not have required capability */
+ AOM_CODEC_INCAPABLE,
+
+ /*!\brief The given bitstream is not supported.
+ *
+ * The bitstream was unable to be parsed at the highest level. The decoder
+ * is unable to proceed. This error \ref SHOULD be treated as fatal to the
+ * stream. */
+ AOM_CODEC_UNSUP_BITSTREAM,
+
+ /*!\brief Encoded bitstream uses an unsupported feature
+ *
+ * The decoder does not implement a feature required by the encoder. This
+ * return code should only be used for features that prevent future
+ * pictures from being properly decoded. This error \ref MAY be treated as
+ * fatal to the stream or \ref MAY be treated as fatal to the current GOP.
+ */
+ AOM_CODEC_UNSUP_FEATURE,
+
+ /*!\brief The coded data for this stream is corrupt or incomplete
+ *
+ * There was a problem decoding the current frame. This return code
+ * should only be used for failures that prevent future pictures from
+ * being properly decoded. This error \ref MAY be treated as fatal to the
+ * stream or \ref MAY be treated as fatal to the current GOP. If decoding
+ * is continued for the current GOP, artifacts may be present.
+ */
+ AOM_CODEC_CORRUPT_FRAME,
+
+ /*!\brief An application-supplied parameter is not valid.
+ *
+ */
+ AOM_CODEC_INVALID_PARAM,
+
+ /*!\brief An iterator reached the end of list.
+ *
+ */
+ AOM_CODEC_LIST_END
+
+} aom_codec_err_t;
+
+/*! \brief Codec capabilities bitfield
+ *
+ * Each codec advertises the capabilities it supports as part of its
+ * ::aom_codec_iface_t interface structure. Capabilities are extra interfaces
+ * or functionality, and are not required to be supported.
+ *
+ * The available flags are specified by AOM_CODEC_CAP_* defines.
+ */
+typedef long aom_codec_caps_t;
+#define AOM_CODEC_CAP_DECODER 0x1 /**< Is a decoder */
+#define AOM_CODEC_CAP_ENCODER 0x2 /**< Is an encoder */
+
+/*! \brief Initialization-time Feature Enabling
+ *
+ * Certain codec features must be known at initialization time, to allow for
+ * proper memory allocation.
+ *
+ * The available flags are specified by AOM_CODEC_USE_* defines.
+ */
+typedef long aom_codec_flags_t;
+
+/*!\brief Time Stamp Type
+ *
+ * An integer, which when multiplied by the stream's time base, provides
+ * the absolute time of a sample.
+ */
+typedef int64_t aom_codec_pts_t;
+
+/*!\brief Codec interface structure.
+ *
+ * Contains function pointers and other data private to the codec
+ * implementation. This structure is opaque to the application. Common
+ * functions used with this structure:
+ * - aom_codec_iface_name(aom_codec_iface_t *iface): get the
+ * name of the codec
+ * - aom_codec_get_caps(aom_codec_iface_t *iface): returns
+ * the capabilities of the codec
+ * - aom_codec_enc_config_default: generate the default config for
+ * initializing the encoder (see documention in aom_encoder.h)
+ * - aom_codec_dec_init, aom_codec_enc_init: initialize the codec context
+ * structure (see documentation on aom_codec_ctx).
+ *
+ * To get access to the AV1 encoder and decoder, use aom_codec_av1_cx() and
+ * aom_codec_av1_dx().
+ */
+typedef const struct aom_codec_iface aom_codec_iface_t;
+
+/*!\brief Codec private data structure.
+ *
+ * Contains data private to the codec implementation. This structure is opaque
+ * to the application.
+ */
+typedef struct aom_codec_priv aom_codec_priv_t;
+
+/*!\brief Compressed Frame Flags
+ *
+ * This type represents a bitfield containing information about a compressed
+ * frame that may be useful to an application. The most significant 16 bits
+ * can be used by an algorithm to provide additional detail, for example to
+ * support frame types that are codec specific (MPEG-1 D-frames for example)
+ */
+typedef uint32_t aom_codec_frame_flags_t;
+#define AOM_FRAME_IS_KEY 0x1 /**< frame is the start of a GOP */
+/*!\brief frame can be dropped without affecting the stream (no future frame
+ * depends on this one) */
+#define AOM_FRAME_IS_DROPPABLE 0x2
+/*!\brief this is an INTRA_ONLY frame */
+#define AOM_FRAME_IS_INTRAONLY 0x10
+/*!\brief this is an S-frame */
+#define AOM_FRAME_IS_SWITCH 0x20
+/*!\brief this is an error-resilient frame */
+#define AOM_FRAME_IS_ERROR_RESILIENT 0x40
+/*!\brief this is a key-frame dependent recovery-point frame */
+#define AOM_FRAME_IS_DELAYED_RANDOM_ACCESS_POINT 0x80
+
+/*!\brief Iterator
+ *
+ * Opaque storage used for iterating over lists.
+ */
+typedef const void *aom_codec_iter_t;
+
+/*!\brief Codec context structure
+ *
+ * All codecs \ref MUST support this context structure fully. In general,
+ * this data should be considered private to the codec algorithm, and
+ * not be manipulated or examined by the calling application. Applications
+ * may reference the 'name' member to get a printable description of the
+ * algorithm.
+ */
+typedef struct aom_codec_ctx {
+ const char *name; /**< Printable interface name */
+ aom_codec_iface_t *iface; /**< Interface pointers */
+ aom_codec_err_t err; /**< Last returned error */
+ const char *err_detail; /**< Detailed info, if available */
+ aom_codec_flags_t init_flags; /**< Flags passed at init time */
+ union {
+ /**< Decoder Configuration Pointer */
+ const struct aom_codec_dec_cfg *dec;
+ /**< Encoder Configuration Pointer */
+ const struct aom_codec_enc_cfg *enc;
+ const void *raw;
+ } config; /**< Configuration pointer aliasing union */
+ aom_codec_priv_t *priv; /**< Algorithm private storage */
+} aom_codec_ctx_t;
+
+/*!\brief Bit depth for codec
+ * *
+ * This enumeration determines the bit depth of the codec.
+ */
+typedef enum aom_bit_depth {
+ AOM_BITS_8 = 8, /**< 8 bits */
+ AOM_BITS_10 = 10, /**< 10 bits */
+ AOM_BITS_12 = 12, /**< 12 bits */
+} aom_bit_depth_t;
+
+/*!\brief Superblock size selection.
+ *
+ * Defines the superblock size used for encoding. The superblock size can
+ * either be fixed at 64x64 or 128x128 pixels, or it can be dynamically
+ * selected by the encoder for each frame.
+ */
+typedef enum aom_superblock_size {
+ AOM_SUPERBLOCK_SIZE_64X64, /**< Always use 64x64 superblocks. */
+ AOM_SUPERBLOCK_SIZE_128X128, /**< Always use 128x128 superblocks. */
+ AOM_SUPERBLOCK_SIZE_DYNAMIC /**< Select superblock size dynamically. */
+} aom_superblock_size_t;
+
+/*
+ * Library Version Number Interface
+ *
+ * For example, see the following sample return values:
+ * aom_codec_version() (1<<16 | 2<<8 | 3)
+ * aom_codec_version_str() "v1.2.3-rc1-16-gec6a1ba"
+ * aom_codec_version_extra_str() "rc1-16-gec6a1ba"
+ */
+
+/*!\brief Return the version information (as an integer)
+ *
+ * Returns a packed encoding of the library version number. This will only
+ * include the major.minor.patch component of the version number. Note that this
+ * encoded value should be accessed through the macros provided, as the encoding
+ * may change in the future.
+ *
+ */
+int aom_codec_version(void);
+
+/*!\brief Return the major version number */
+#define aom_codec_version_major() ((aom_codec_version() >> 16) & 0xff)
+
+/*!\brief Return the minor version number */
+#define aom_codec_version_minor() ((aom_codec_version() >> 8) & 0xff)
+
+/*!\brief Return the patch version number */
+#define aom_codec_version_patch() ((aom_codec_version() >> 0) & 0xff)
+
+/*!\brief Return the version information (as a string)
+ *
+ * Returns a printable string containing the full library version number. This
+ * may contain additional text following the three digit version number, as to
+ * indicate release candidates, prerelease versions, etc.
+ *
+ */
+const char *aom_codec_version_str(void);
+
+/*!\brief Return the version information (as a string)
+ *
+ * Returns a printable "extra string". This is the component of the string
+ * returned by aom_codec_version_str() following the three digit version number.
+ *
+ */
+const char *aom_codec_version_extra_str(void);
+
+/*!\brief Return the build configuration
+ *
+ * Returns a printable string containing an encoded version of the build
+ * configuration. This may be useful to aom support.
+ *
+ */
+const char *aom_codec_build_config(void);
+
+/*!\brief Return the name for a given interface
+ *
+ * Returns a human readable string for name of the given codec interface.
+ *
+ * \param[in] iface Interface pointer
+ *
+ */
+const char *aom_codec_iface_name(aom_codec_iface_t *iface);
+
+/*!\brief Convert error number to printable string
+ *
+ * Returns a human readable string for the last error returned by the
+ * algorithm. The returned error will be one line and will not contain
+ * any newline characters.
+ *
+ *
+ * \param[in] err Error number.
+ *
+ */
+const char *aom_codec_err_to_string(aom_codec_err_t err);
+
+/*!\brief Retrieve error synopsis for codec context
+ *
+ * Returns a human readable string for the last error returned by the
+ * algorithm. The returned error will be one line and will not contain
+ * any newline characters.
+ *
+ *
+ * \param[in] ctx Pointer to this instance's context.
+ *
+ */
+const char *aom_codec_error(aom_codec_ctx_t *ctx);
+
+/*!\brief Retrieve detailed error information for codec context
+ *
+ * Returns a human readable string providing detailed information about
+ * the last error.
+ *
+ * \param[in] ctx Pointer to this instance's context.
+ *
+ * \retval NULL
+ * No detailed information is available.
+ */
+const char *aom_codec_error_detail(aom_codec_ctx_t *ctx);
+
+/* REQUIRED FUNCTIONS
+ *
+ * The following functions are required to be implemented for all codecs.
+ * They represent the base case functionality expected of all codecs.
+ */
+
+/*!\brief Destroy a codec instance
+ *
+ * Destroys a codec context, freeing any associated memory buffers.
+ *
+ * \param[in] ctx Pointer to this instance's context
+ *
+ * \retval #AOM_CODEC_OK
+ * The codec algorithm initialized.
+ * \retval #AOM_CODEC_MEM_ERROR
+ * Memory allocation failed.
+ */
+aom_codec_err_t aom_codec_destroy(aom_codec_ctx_t *ctx);
+
+/*!\brief Get the capabilities of an algorithm.
+ *
+ * Retrieves the capabilities bitfield from the algorithm's interface.
+ *
+ * \param[in] iface Pointer to the algorithm interface
+ *
+ */
+aom_codec_caps_t aom_codec_get_caps(aom_codec_iface_t *iface);
+
+/*!\name Codec Control
+ *
+ * The aom_codec_control function exchanges algorithm specific data with the
+ * codec instance. Additionally, the macro AOM_CODEC_CONTROL_TYPECHECKED is
+ * provided, which will type-check the parameter against the control ID before
+ * calling aom_codec_control - note that this macro requires the control ID
+ * to be directly encoded in it, e.g.,
+ * AOM_CODEC_CONTROL_TYPECHECKED(&ctx, AOME_SET_CPUUSED, 8).
+ *
+ * The codec control IDs can be found in aom.h, aomcx.h, and aomdx.h
+ * (defined as aom_com_control_id, aome_enc_control_id, and aom_dec_control_id).
+ * @{
+ */
+/*!\brief Algorithm Control
+ *
+ * aom_codec_control takes a context, a control ID, and a third parameter
+ * (with varying type). If the context is non-null and an error occurs,
+ * ctx->err will be set to the same value as the return value.
+ *
+ * \param[in] ctx Pointer to this instance's context
+ * \param[in] ctrl_id Algorithm specific control identifier.
+ * Must be nonzero.
+ *
+ * \retval #AOM_CODEC_OK
+ * The control request was processed.
+ * \retval #AOM_CODEC_ERROR
+ * The control request was not processed.
+ * \retval #AOM_CODEC_INVALID_PARAM
+ * The control ID was zero, or the data was not valid.
+ */
+aom_codec_err_t aom_codec_control(aom_codec_ctx_t *ctx, int ctrl_id, ...);
+
+/*!\brief Key & Value API
+ *
+ * aom_codec_set_option() takes a context, a key (option name) and a value. If
+ * the context is non-null and an error occurs, ctx->err will be set to the same
+ * value as the return value.
+ *
+ * \param[in] ctx Pointer to this instance's context
+ * \param[in] name The name of the option (key)
+ * \param[in] value The value of the option
+ *
+ * \retval #AOM_CODEC_OK
+ * The value of the option was set.
+ * \retval #AOM_CODEC_INVALID_PARAM
+ * The data was not valid.
+ * \retval #AOM_CODEC_ERROR
+ * The option was not successfully set.
+ */
+aom_codec_err_t aom_codec_set_option(aom_codec_ctx_t *ctx, const char *name,
+ const char *value);
+
+/*!\brief aom_codec_control wrapper macro (adds type-checking, less flexible)
+ *
+ * This macro allows for type safe conversions across the variadic parameter
+ * to aom_codec_control(). However, it requires the explicit control ID
+ * be passed in (it cannot be passed in via a variable) -- otherwise a compiler
+ * error will occur. After the type checking, it calls aom_codec_control.
+ */
+#define AOM_CODEC_CONTROL_TYPECHECKED(ctx, id, data) \
+ aom_codec_control_typechecked_##id(ctx, id, data) /**<\hideinitializer*/
+
+/*!\brief Creates typechecking mechanisms for aom_codec_control
+ *
+ * It defines a static function with the correctly typed arguments as a wrapper
+ * to the type-unsafe aom_codec_control function. It also creates a typedef
+ * for each type.
+ */
+#define AOM_CTRL_USE_TYPE(id, typ) \
+ static aom_codec_err_t aom_codec_control_typechecked_##id( \
+ aom_codec_ctx_t *, int, typ) AOM_UNUSED; \
+ static aom_codec_err_t aom_codec_control_typechecked_##id( \
+ aom_codec_ctx_t *ctx, int ctrl, typ data) { \
+ return aom_codec_control(ctx, ctrl, data); \
+ } /**<\hideinitializer*/ \
+ typedef typ aom_codec_control_type_##id;
+/*!@} end Codec Control group */
+
+/*!\brief OBU types. */
+typedef enum ATTRIBUTE_PACKED {
+ OBU_SEQUENCE_HEADER = 1,
+ OBU_TEMPORAL_DELIMITER = 2,
+ OBU_FRAME_HEADER = 3,
+ OBU_TILE_GROUP = 4,
+ OBU_METADATA = 5,
+ OBU_FRAME = 6,
+ OBU_REDUNDANT_FRAME_HEADER = 7,
+ OBU_TILE_LIST = 8,
+ OBU_PADDING = 15,
+} OBU_TYPE;
+
+/*!\brief OBU metadata types. */
+typedef enum {
+ OBU_METADATA_TYPE_AOM_RESERVED_0 = 0,
+ OBU_METADATA_TYPE_HDR_CLL = 1,
+ OBU_METADATA_TYPE_HDR_MDCV = 2,
+ OBU_METADATA_TYPE_SCALABILITY = 3,
+ OBU_METADATA_TYPE_ITUT_T35 = 4,
+ OBU_METADATA_TYPE_TIMECODE = 5,
+} OBU_METADATA_TYPE;
+
+/*!\brief Returns string representation of OBU_TYPE.
+ *
+ * \param[in] type The OBU_TYPE to convert to string.
+ */
+const char *aom_obu_type_to_string(OBU_TYPE type);
+
+/*!@} - end defgroup codec*/
+#ifdef __cplusplus
+}
+#endif
+#endif // AOM_AOM_AOM_CODEC_H_
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_decoder.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_decoder.h
new file mode 100644
index 0000000..5ce7c7b
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_decoder.h
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+#ifndef AOM_AOM_AOM_DECODER_H_
+#define AOM_AOM_AOM_DECODER_H_
+
+/*!\defgroup decoder Decoder Algorithm Interface
+ * \ingroup codec
+ * This abstraction allows applications using this decoder to easily support
+ * multiple video formats with minimal code duplication. This section describes
+ * the interface common to all decoders.
+ * @{
+ */
+
+/*!\file
+ * \brief Describes the decoder algorithm interface to applications.
+ *
+ * This file describes the interface between an application and a
+ * video decoder algorithm.
+ *
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "aom/aom_codec.h"
+#include "aom/aom_frame_buffer.h"
+
+/*!\brief Current ABI version number
+ *
+ * \internal
+ * If this file is altered in any way that changes the ABI, this value
+ * must be bumped. Examples include, but are not limited to, changing
+ * types, removing or reassigning enums, adding/removing/rearranging
+ * fields to structures
+ */
+#define AOM_DECODER_ABI_VERSION \
+ (6 + AOM_CODEC_ABI_VERSION) /**<\hideinitializer*/
+
+/*! \brief Decoder capabilities bitfield
+ *
+ * Each decoder advertises the capabilities it supports as part of its
+ * ::aom_codec_iface_t interface structure. Capabilities are extra interfaces
+ * or functionality, and are not required to be supported by a decoder.
+ *
+ * The available flags are specified by AOM_CODEC_CAP_* defines.
+ */
+/*!brief Can support external frame buffers */
+#define AOM_CODEC_CAP_EXTERNAL_FRAME_BUFFER 0x200000
+
+/*! \brief Initialization-time Feature Enabling
+ *
+ * Certain codec features must be known at initialization time, to allow for
+ * proper memory allocation.
+ *
+ * The available flags are specified by AOM_CODEC_USE_* defines.
+ */
+
+/*!\brief Stream properties
+ *
+ * This structure is used to query or set properties of the decoded
+ * stream.
+ */
+typedef struct aom_codec_stream_info {
+ unsigned int w; /**< Width (or 0 for unknown/default) */
+ unsigned int h; /**< Height (or 0 for unknown/default) */
+ unsigned int is_kf; /**< Current frame is a keyframe */
+ unsigned int number_spatial_layers; /**< Number of spatial layers */
+ unsigned int number_temporal_layers; /**< Number of temporal layers */
+ unsigned int is_annexb; /**< Is Bitstream in Annex-B format */
+} aom_codec_stream_info_t;
+
+/* REQUIRED FUNCTIONS
+ *
+ * The following functions are required to be implemented for all decoders.
+ * They represent the base case functionality expected of all decoders.
+ */
+
+/*!\brief Initialization Configurations
+ *
+ * This structure is used to pass init time configuration options to the
+ * decoder.
+ */
+typedef struct aom_codec_dec_cfg {
+ unsigned int threads; /**< Maximum number of threads to use, default 1 */
+ unsigned int w; /**< Width */
+ unsigned int h; /**< Height */
+ unsigned int allow_lowbitdepth; /**< Allow use of low-bitdepth coding path */
+} aom_codec_dec_cfg_t; /**< alias for struct aom_codec_dec_cfg */
+
+/*!\brief Initialize a decoder instance
+ *
+ * Initializes a decoder context using the given interface. Applications
+ * should call the aom_codec_dec_init convenience macro instead of this
+ * function directly, to ensure that the ABI version number parameter
+ * is properly initialized.
+ *
+ * If the library was configured with cmake -DCONFIG_MULTITHREAD=0, this
+ * call is not thread safe and should be guarded with a lock if being used
+ * in a multithreaded context.
+ *
+ * \param[in] ctx Pointer to this instance's context.
+ * \param[in] iface Pointer to the algorithm interface to use.
+ * \param[in] cfg Configuration to use, if known. May be NULL.
+ * \param[in] flags Bitfield of AOM_CODEC_USE_* flags
+ * \param[in] ver ABI version number. Must be set to
+ * AOM_DECODER_ABI_VERSION
+ * \retval #AOM_CODEC_OK
+ * The decoder algorithm initialized.
+ * \retval #AOM_CODEC_MEM_ERROR
+ * Memory allocation failed.
+ */
+aom_codec_err_t aom_codec_dec_init_ver(aom_codec_ctx_t *ctx,
+ aom_codec_iface_t *iface,
+ const aom_codec_dec_cfg_t *cfg,
+ aom_codec_flags_t flags, int ver);
+
+/*!\brief Convenience macro for aom_codec_dec_init_ver()
+ *
+ * Ensures the ABI version parameter is properly set.
+ */
+#define aom_codec_dec_init(ctx, iface, cfg, flags) \
+ aom_codec_dec_init_ver(ctx, iface, cfg, flags, AOM_DECODER_ABI_VERSION)
+
+/*!\brief Parse stream info from a buffer
+ *
+ * Performs high level parsing of the bitstream. Construction of a decoder
+ * context is not necessary. Can be used to determine if the bitstream is
+ * of the proper format, and to extract information from the stream.
+ *
+ * \param[in] iface Pointer to the algorithm interface
+ * \param[in] data Pointer to a block of data to parse
+ * \param[in] data_sz Size of the data buffer
+ * \param[in,out] si Pointer to stream info to update. The is_annexb
+ * member \ref MUST be properly initialized. This
+ * function sets the rest of the members.
+ *
+ * \retval #AOM_CODEC_OK
+ * Bitstream is parsable and stream information updated.
+ * \retval #AOM_CODEC_INVALID_PARAM
+ * One of the arguments is invalid, for example a NULL pointer.
+ * \retval #AOM_CODEC_UNSUP_BITSTREAM
+ * The decoder didn't recognize the coded data, or the
+ * buffer was too short.
+ */
+aom_codec_err_t aom_codec_peek_stream_info(aom_codec_iface_t *iface,
+ const uint8_t *data, size_t data_sz,
+ aom_codec_stream_info_t *si);
+
+/*!\brief Return information about the current stream.
+ *
+ * Returns information about the stream that has been parsed during decoding.
+ *
+ * \param[in] ctx Pointer to this instance's context
+ * \param[in,out] si Pointer to stream info to update.
+ *
+ * \retval #AOM_CODEC_OK
+ * Bitstream is parsable and stream information updated.
+ * \retval #AOM_CODEC_INVALID_PARAM
+ * One of the arguments is invalid, for example a NULL pointer.
+ * \retval #AOM_CODEC_UNSUP_BITSTREAM
+ * The decoder couldn't parse the submitted data.
+ */
+aom_codec_err_t aom_codec_get_stream_info(aom_codec_ctx_t *ctx,
+ aom_codec_stream_info_t *si);
+
+/*!\brief Decode data
+ *
+ * Processes a buffer of coded data. Encoded data \ref MUST be passed in DTS
+ * (decode time stamp) order. Frames produced will always be in PTS
+ * (presentation time stamp) order.
+ *
+ * \param[in] ctx Pointer to this instance's context
+ * \param[in] data Pointer to this block of new coded data.
+ * \param[in] data_sz Size of the coded data, in bytes.
+ * \param[in] user_priv Application specific data to associate with
+ * this frame.
+ *
+ * \return Returns #AOM_CODEC_OK if the coded data was processed completely
+ * and future pictures can be decoded without error. Otherwise,
+ * see the descriptions of the other error codes in ::aom_codec_err_t
+ * for recoverability capabilities.
+ */
+aom_codec_err_t aom_codec_decode(aom_codec_ctx_t *ctx, const uint8_t *data,
+ size_t data_sz, void *user_priv);
+
+/*!\brief Decoded frames iterator
+ *
+ * Iterates over a list of the frames available for display. The iterator
+ * storage should be initialized to NULL to start the iteration. Iteration is
+ * complete when this function returns NULL.
+ *
+ * The list of available frames becomes valid upon completion of the
+ * aom_codec_decode call, and remains valid until the next call to
+ * aom_codec_decode.
+ *
+ * \param[in] ctx Pointer to this instance's context
+ * \param[in,out] iter Iterator storage, initialized to NULL
+ *
+ * \return Returns a pointer to an image, if one is ready for display. Frames
+ * produced will always be in PTS (presentation time stamp) order.
+ */
+aom_image_t *aom_codec_get_frame(aom_codec_ctx_t *ctx, aom_codec_iter_t *iter);
+
+/*!\defgroup cap_external_frame_buffer External Frame Buffer Functions
+ *
+ * The following function is required to be implemented for all decoders
+ * that advertise the AOM_CODEC_CAP_EXTERNAL_FRAME_BUFFER capability.
+ * Calling this function for codecs that don't advertise this capability
+ * will result in an error code being returned, usually AOM_CODEC_INCAPABLE.
+ * @{
+ */
+
+/*!\brief Pass in external frame buffers for the decoder to use.
+ *
+ * Registers functions to be called when libaom needs a frame buffer
+ * to decode the current frame and a function to be called when libaom does
+ * not internally reference the frame buffer. This set function must
+ * be called before the first call to decode or libaom will assume the
+ * default behavior of allocating frame buffers internally.
+ *
+ * \param[in] ctx Pointer to this instance's context
+ * \param[in] cb_get Pointer to the get callback function
+ * \param[in] cb_release Pointer to the release callback function
+ * \param[in] cb_priv Callback's private data
+ *
+ * \retval #AOM_CODEC_OK
+ * External frame buffers will be used by libaom.
+ * \retval #AOM_CODEC_INVALID_PARAM
+ * One or more of the callbacks were NULL.
+ * \retval #AOM_CODEC_ERROR
+ * Decoder context not initialized.
+ * \retval #AOM_CODEC_INCAPABLE
+ * Algorithm not capable of using external frame buffers.
+ *
+ * \note
+ * When decoding AV1, the application may be required to pass in at least
+ * #AOM_MAXIMUM_WORK_BUFFERS external frame buffers.
+ */
+aom_codec_err_t aom_codec_set_frame_buffer_functions(
+ aom_codec_ctx_t *ctx, aom_get_frame_buffer_cb_fn_t cb_get,
+ aom_release_frame_buffer_cb_fn_t cb_release, void *cb_priv);
+
+/*!@} - end defgroup cap_external_frame_buffer */
+
+/*!@} - end defgroup decoder*/
+#ifdef __cplusplus
+}
+#endif
+#endif // AOM_AOM_AOM_DECODER_H_
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_encoder.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_encoder.h
new file mode 100644
index 0000000..7009018
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_encoder.h
@@ -0,0 +1,1131 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+#ifndef AOM_AOM_AOM_ENCODER_H_
+#define AOM_AOM_AOM_ENCODER_H_
+
+/*!\defgroup encoder Encoder Algorithm Interface
+ * \ingroup codec
+ * This abstraction allows applications using this encoder to easily support
+ * multiple video formats with minimal code duplication. This section describes
+ * the interface common to all encoders.
+ * @{
+ */
+
+/*!\file
+ * \brief Describes the encoder algorithm interface to applications.
+ *
+ * This file describes the interface between an application and a
+ * video encoder algorithm.
+ *
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "aom/aom_codec.h"
+#include "aom/aom_external_partition.h"
+
+/*!\brief Current ABI version number
+ *
+ * \hideinitializer
+ * \internal
+ * If this file is altered in any way that changes the ABI, this value
+ * must be bumped. Examples include, but are not limited to, changing
+ * types, removing or reassigning enums, adding/removing/rearranging
+ * fields to structures
+ *
+ * Note: In the definition of AOM_ENCODER_ABI_VERSION, 3 is the value of
+ * AOM_EXT_PART_ABI_VERSION in libaom v3.2.0. The old value of
+ * AOM_EXT_PART_ABI_VERSION is used so as to not break the ABI version check in
+ * aom_codec_enc_init_ver() when an application compiled against libaom v3.2.0
+ * passes the old value of AOM_ENCODER_ABI_VERSION to aom_codec_enc_init_ver().
+ * The external partition API is still experimental. When it is declared stable,
+ * we will replace 3 with AOM_EXT_PART_ABI_VERSION in the definition of
+ * AOM_ENCODER_ABI_VERSION.
+ */
+#define AOM_ENCODER_ABI_VERSION \
+ (10 + AOM_CODEC_ABI_VERSION + /*AOM_EXT_PART_ABI_VERSION=*/3)
+
+/*! \brief Encoder capabilities bitfield
+ *
+ * Each encoder advertises the capabilities it supports as part of its
+ * ::aom_codec_iface_t interface structure. Capabilities are extra
+ * interfaces or functionality, and are not required to be supported
+ * by an encoder.
+ *
+ * The available flags are specified by AOM_CODEC_CAP_* defines.
+ */
+#define AOM_CODEC_CAP_PSNR 0x10000 /**< Can issue PSNR packets */
+
+/*! Can support input images at greater than 8 bitdepth.
+ */
+#define AOM_CODEC_CAP_HIGHBITDEPTH 0x40000
+
+/*! \brief Initialization-time Feature Enabling
+ *
+ * Certain codec features must be known at initialization time, to allow
+ * for proper memory allocation.
+ *
+ * The available flags are specified by AOM_CODEC_USE_* defines.
+ */
+#define AOM_CODEC_USE_PSNR 0x10000 /**< Calculate PSNR on each frame */
+/*!\brief Make the encoder output one partition at a time. */
+#define AOM_CODEC_USE_HIGHBITDEPTH 0x40000 /**< Use high bitdepth */
+
+/*!\brief Generic fixed size buffer structure
+ *
+ * This structure is able to hold a reference to any fixed size buffer.
+ */
+typedef struct aom_fixed_buf {
+ void *buf; /**< Pointer to the data. Does NOT own the data! */
+ size_t sz; /**< Length of the buffer, in chars */
+} aom_fixed_buf_t; /**< alias for struct aom_fixed_buf */
+
+/*!\brief Error Resilient flags
+ *
+ * These flags define which error resilient features to enable in the
+ * encoder. The flags are specified through the
+ * aom_codec_enc_cfg::g_error_resilient variable.
+ */
+typedef uint32_t aom_codec_er_flags_t;
+/*!\brief Improve resiliency against losses of whole frames */
+#define AOM_ERROR_RESILIENT_DEFAULT 0x1
+
+/*!\brief Encoder output packet variants
+ *
+ * This enumeration lists the different kinds of data packets that can be
+ * returned by calls to aom_codec_get_cx_data(). Algorithms \ref MAY
+ * extend this list to provide additional functionality.
+ */
+enum aom_codec_cx_pkt_kind {
+ AOM_CODEC_CX_FRAME_PKT, /**< Compressed video frame */
+ AOM_CODEC_STATS_PKT, /**< Two-pass statistics for this frame */
+ AOM_CODEC_FPMB_STATS_PKT, /**< first pass mb statistics for this frame */
+ AOM_CODEC_PSNR_PKT, /**< PSNR statistics for this frame */
+ AOM_CODEC_CUSTOM_PKT = 256 /**< Algorithm extensions */
+};
+
+/*!\brief Encoder output packet
+ *
+ * This structure contains the different kinds of output data the encoder
+ * may produce while compressing a frame.
+ */
+typedef struct aom_codec_cx_pkt {
+ enum aom_codec_cx_pkt_kind kind; /**< packet variant */
+ union {
+ struct {
+ void *buf; /**< compressed data buffer */
+ size_t sz; /**< length of compressed data */
+ /*!\brief time stamp to show frame (in timebase units) */
+ aom_codec_pts_t pts;
+ /*!\brief duration to show frame (in timebase units) */
+ unsigned long duration;
+ aom_codec_frame_flags_t flags; /**< flags for this frame */
+ /*!\brief the partition id defines the decoding order of the partitions.
+ * Only applicable when "output partition" mode is enabled. First
+ * partition has id 0.*/
+ int partition_id;
+ /*!\brief size of the visible frame in this packet */
+ size_t vis_frame_size;
+ } frame; /**< data for compressed frame packet */
+ aom_fixed_buf_t twopass_stats; /**< data for two-pass packet */
+ aom_fixed_buf_t firstpass_mb_stats; /**< first pass mb packet */
+ struct aom_psnr_pkt {
+ unsigned int samples[4]; /**< Number of samples, total/y/u/v */
+ uint64_t sse[4]; /**< sum squared error, total/y/u/v */
+ double psnr[4]; /**< PSNR, total/y/u/v */
+ /*!\brief Number of samples, total/y/u/v when
+ * input bit-depth < stream bit-depth.*/
+ unsigned int samples_hbd[4];
+ /*!\brief sum squared error, total/y/u/v when
+ * input bit-depth < stream bit-depth.*/
+ uint64_t sse_hbd[4];
+ /*!\brief PSNR, total/y/u/v when
+ * input bit-depth < stream bit-depth.*/
+ double psnr_hbd[4];
+ } psnr; /**< data for PSNR packet */
+ aom_fixed_buf_t raw; /**< data for arbitrary packets */
+ } data; /**< packet data */
+} aom_codec_cx_pkt_t; /**< alias for struct aom_codec_cx_pkt */
+
+/*!\brief Rational Number
+ *
+ * This structure holds a fractional value.
+ */
+typedef struct aom_rational {
+ int num; /**< fraction numerator */
+ int den; /**< fraction denominator */
+} aom_rational_t; /**< alias for struct aom_rational */
+
+/*!\brief Multi-pass Encoding Pass
+ *
+ * AOM_RC_LAST_PASS is kept for backward compatibility.
+ * If passes is not given and pass==2, the codec will assume passes=2.
+ * For new code, it is recommended to use AOM_RC_SECOND_PASS and set
+ * the "passes" member to 2 via the key & val API for two-pass encoding.
+ */
+enum aom_enc_pass {
+ AOM_RC_ONE_PASS = 0, /**< Single pass mode */
+ AOM_RC_FIRST_PASS = 1, /**< First pass of multi-pass mode */
+ AOM_RC_SECOND_PASS = 2, /**< Second pass of multi-pass mode */
+ AOM_RC_THIRD_PASS = 3, /**< Third pass of multi-pass mode */
+ AOM_RC_LAST_PASS = 2, /**< Final pass of two-pass mode */
+};
+
+/*!\brief Rate control mode */
+enum aom_rc_mode {
+ AOM_VBR, /**< Variable Bit Rate (VBR) mode */
+ AOM_CBR, /**< Constant Bit Rate (CBR) mode */
+ AOM_CQ, /**< Constrained Quality (CQ) mode */
+ AOM_Q, /**< Constant Quality (Q) mode */
+};
+
+/*!\brief Keyframe placement mode.
+ *
+ * This enumeration determines whether keyframes are placed automatically by
+ * the encoder or whether this behavior is disabled. Older releases of this
+ * SDK were implemented such that AOM_KF_FIXED meant keyframes were disabled.
+ * This name is confusing for this behavior, so the new symbols to be used
+ * are AOM_KF_AUTO and AOM_KF_DISABLED.
+ */
+enum aom_kf_mode {
+ AOM_KF_FIXED, /**< deprecated, implies AOM_KF_DISABLED */
+ AOM_KF_AUTO, /**< Encoder determines optimal placement automatically */
+ AOM_KF_DISABLED = 0 /**< Encoder does not place keyframes. */
+};
+
+/*!\brief Frame super-resolution mode. */
+typedef enum {
+ /**< Frame super-resolution is disabled for all frames. */
+ AOM_SUPERRES_NONE,
+ /**< All frames are coded at the specified scale and super-resolved. */
+ AOM_SUPERRES_FIXED,
+ /**< All frames are coded at a random scale and super-resolved. */
+ AOM_SUPERRES_RANDOM,
+ /**< Super-resolution scale for each frame is determined based on the q index
+ of that frame. */
+ AOM_SUPERRES_QTHRESH,
+ /**< Full-resolution or super-resolution and the scale (in case of
+ super-resolution) are automatically selected for each frame. */
+ AOM_SUPERRES_AUTO,
+} aom_superres_mode;
+
+/*!\brief Encoder Config Options
+ *
+ * This type allows to enumerate and control flags defined for encoder control
+ * via config file at runtime.
+ */
+typedef struct cfg_options {
+ /*!\brief Indicate init by cfg file
+ * 0 or 1
+ */
+ unsigned int init_by_cfg_file;
+ /*!\brief Superblock size
+ * 0, 64 or 128
+ */
+ unsigned int super_block_size;
+ /*!\brief max partition size
+ * 8, 16, 32, 64, 128
+ */
+ unsigned int max_partition_size;
+ /*!\brief min partition size
+ * 8, 16, 32, 64, 128
+ */
+ unsigned int min_partition_size;
+ /*!\brief disable AB Shape partition type
+ *
+ */
+ unsigned int disable_ab_partition_type;
+ /*!\brief disable rectangular partition type
+ *
+ */
+ unsigned int disable_rect_partition_type;
+ /*!\brief disable 1:4/4:1 partition type
+ *
+ */
+ unsigned int disable_1to4_partition_type;
+ /*!\brief disable flip and identity transform type
+ *
+ */
+ unsigned int disable_flip_idtx;
+ /*!\brief disable CDEF filter
+ *
+ */
+ unsigned int disable_cdef;
+ /*!\brief disable Loop Restoration Filter
+ *
+ */
+ unsigned int disable_lr;
+ /*!\brief disable OBMC
+ *
+ */
+ unsigned int disable_obmc;
+ /*!\brief disable Warped Motion
+ *
+ */
+ unsigned int disable_warp_motion;
+ /*!\brief disable global motion
+ *
+ */
+ unsigned int disable_global_motion;
+ /*!\brief disable dist weighted compound
+ *
+ */
+ unsigned int disable_dist_wtd_comp;
+ /*!\brief disable diff weighted compound
+ *
+ */
+ unsigned int disable_diff_wtd_comp;
+ /*!\brief disable inter/intra compound
+ *
+ */
+ unsigned int disable_inter_intra_comp;
+ /*!\brief disable masked compound
+ *
+ */
+ unsigned int disable_masked_comp;
+ /*!\brief disable one sided compound
+ *
+ */
+ unsigned int disable_one_sided_comp;
+ /*!\brief disable Palette
+ *
+ */
+ unsigned int disable_palette;
+ /*!\brief disable Intra Block Copy
+ *
+ */
+ unsigned int disable_intrabc;
+ /*!\brief disable chroma from luma
+ *
+ */
+ unsigned int disable_cfl;
+ /*!\brief disable intra smooth mode
+ *
+ */
+ unsigned int disable_smooth_intra;
+ /*!\brief disable filter intra
+ *
+ */
+ unsigned int disable_filter_intra;
+ /*!\brief disable dual filter
+ *
+ */
+ unsigned int disable_dual_filter;
+ /*!\brief disable intra angle delta
+ *
+ */
+ unsigned int disable_intra_angle_delta;
+ /*!\brief disable intra edge filter
+ *
+ */
+ unsigned int disable_intra_edge_filter;
+ /*!\brief disable 64x64 transform
+ *
+ */
+ unsigned int disable_tx_64x64;
+ /*!\brief disable smooth inter/intra
+ *
+ */
+ unsigned int disable_smooth_inter_intra;
+ /*!\brief disable inter/inter wedge comp
+ *
+ */
+ unsigned int disable_inter_inter_wedge;
+ /*!\brief disable inter/intra wedge comp
+ *
+ */
+ unsigned int disable_inter_intra_wedge;
+ /*!\brief disable paeth intra
+ *
+ */
+ unsigned int disable_paeth_intra;
+ /*!\brief disable trellis quantization
+ *
+ */
+ unsigned int disable_trellis_quant;
+ /*!\brief disable ref frame MV
+ *
+ */
+ unsigned int disable_ref_frame_mv;
+ /*!\brief use reduced reference frame set
+ *
+ */
+ unsigned int reduced_reference_set;
+ /*!\brief use reduced transform type set
+ *
+ */
+ unsigned int reduced_tx_type_set;
+} cfg_options_t;
+
+/*!\brief Encoded Frame Flags
+ *
+ * This type indicates a bitfield to be passed to aom_codec_encode(), defining
+ * per-frame boolean values. By convention, bits common to all codecs will be
+ * named AOM_EFLAG_*, and bits specific to an algorithm will be named
+ * /algo/_eflag_*. The lower order 16 bits are reserved for common use.
+ */
+typedef long aom_enc_frame_flags_t;
+/*!\brief Force this frame to be a keyframe */
+#define AOM_EFLAG_FORCE_KF (1 << 0)
+
+/*!\brief Encoder configuration structure
+ *
+ * This structure contains the encoder settings that have common representations
+ * across all codecs. This doesn't imply that all codecs support all features,
+ * however.
+ */
+typedef struct aom_codec_enc_cfg {
+ /*
+ * generic settings (g)
+ */
+
+ /*!\brief Algorithm specific "usage" value
+ *
+ * Algorithms may define multiple values for usage, which may convey the
+ * intent of how the application intends to use the stream. If this value
+ * is non-zero, consult the documentation for the codec to determine its
+ * meaning.
+ */
+ unsigned int g_usage;
+
+ /*!\brief Maximum number of threads to use
+ *
+ * For multi-threaded implementations, use no more than this number of
+ * threads. The codec may use fewer threads than allowed. The value
+ * 0 is equivalent to the value 1.
+ */
+ unsigned int g_threads;
+
+ /*!\brief Bitstream profile to use
+ *
+ * Some codecs support a notion of multiple bitstream profiles. Typically
+ * this maps to a set of features that are turned on or off. Often the
+ * profile to use is determined by the features of the intended decoder.
+ * Consult the documentation for the codec to determine the valid values
+ * for this parameter, or set to zero for a sane default.
+ */
+ unsigned int g_profile; /**< profile of bitstream to use */
+
+ /*!\brief Width of the frame
+ *
+ * This value identifies the presentation resolution of the frame,
+ * in pixels. Note that the frames passed as input to the encoder must
+ * have this resolution. Frames will be presented by the decoder in this
+ * resolution, independent of any spatial resampling the encoder may do.
+ */
+ unsigned int g_w;
+
+ /*!\brief Height of the frame
+ *
+ * This value identifies the presentation resolution of the frame,
+ * in pixels. Note that the frames passed as input to the encoder must
+ * have this resolution. Frames will be presented by the decoder in this
+ * resolution, independent of any spatial resampling the encoder may do.
+ */
+ unsigned int g_h;
+
+ /*!\brief Max number of frames to encode
+ *
+ */
+ unsigned int g_limit;
+
+ /*!\brief Forced maximum width of the frame
+ *
+ * If this value is non-zero then it is used to force the maximum frame
+ * width written in write_sequence_header().
+ */
+ unsigned int g_forced_max_frame_width;
+
+ /*!\brief Forced maximum height of the frame
+ *
+ * If this value is non-zero then it is used to force the maximum frame
+ * height written in write_sequence_header().
+ */
+ unsigned int g_forced_max_frame_height;
+
+ /*!\brief Bit-depth of the codec
+ *
+ * This value identifies the bit_depth of the codec,
+ * Only certain bit-depths are supported as identified in the
+ * aom_bit_depth_t enum.
+ */
+ aom_bit_depth_t g_bit_depth;
+
+ /*!\brief Bit-depth of the input frames
+ *
+ * This value identifies the bit_depth of the input frames in bits.
+ * Note that the frames passed as input to the encoder must have
+ * this bit-depth.
+ */
+ unsigned int g_input_bit_depth;
+
+ /*!\brief Stream timebase units
+ *
+ * Indicates the smallest interval of time, in seconds, used by the stream.
+ * For fixed frame rate material, or variable frame rate material where
+ * frames are timed at a multiple of a given clock (ex: video capture),
+ * the \ref RECOMMENDED method is to set the timebase to the reciprocal
+ * of the frame rate (ex: 1001/30000 for 29.970 Hz NTSC). This allows the
+ * pts to correspond to the frame number, which can be handy. For
+ * re-encoding video from containers with absolute time timestamps, the
+ * \ref RECOMMENDED method is to set the timebase to that of the parent
+ * container or multimedia framework (ex: 1/1000 for ms, as in FLV).
+ */
+ struct aom_rational g_timebase;
+
+ /*!\brief Enable error resilient modes.
+ *
+ * The error resilient bitfield indicates to the encoder which features
+ * it should enable to take measures for streaming over lossy or noisy
+ * links.
+ */
+ aom_codec_er_flags_t g_error_resilient;
+
+ /*!\brief Multi-pass Encoding Mode
+ *
+ * This value should be set to the current phase for multi-pass encoding.
+ * For single pass, set to #AOM_RC_ONE_PASS.
+ */
+ enum aom_enc_pass g_pass;
+
+ /*!\brief Allow lagged encoding
+ *
+ * If set, this value allows the encoder to consume a number of input
+ * frames before producing output frames. This allows the encoder to
+ * base decisions for the current frame on future frames. This does
+ * increase the latency of the encoding pipeline, so it is not appropriate
+ * in all situations (ex: realtime encoding).
+ *
+ * Note that this is a maximum value -- the encoder may produce frames
+ * sooner than the given limit. Set this value to 0 to disable this
+ * feature.
+ */
+ unsigned int g_lag_in_frames;
+
+ /*
+ * rate control settings (rc)
+ */
+
+ /*!\brief Temporal resampling configuration, if supported by the codec.
+ *
+ * Temporal resampling allows the codec to "drop" frames as a strategy to
+ * meet its target data rate. This can cause temporal discontinuities in
+ * the encoded video, which may appear as stuttering during playback. This
+ * trade-off is often acceptable, but for many applications is not. It can
+ * be disabled in these cases.
+ *
+ * Note that not all codecs support this feature. All aom AVx codecs do.
+ * For other codecs, consult the documentation for that algorithm.
+ *
+ * This threshold is described as a percentage of the target data buffer.
+ * When the data buffer falls below this percentage of fullness, a
+ * dropped frame is indicated. Set the threshold to zero (0) to disable
+ * this feature.
+ */
+ unsigned int rc_dropframe_thresh;
+
+ /*!\brief Mode for spatial resampling, if supported by the codec.
+ *
+ * Spatial resampling allows the codec to compress a lower resolution
+ * version of the frame, which is then upscaled by the decoder to the
+ * correct presentation resolution. This increases visual quality at
+ * low data rates, at the expense of CPU time on the encoder/decoder.
+ */
+ unsigned int rc_resize_mode;
+
+ /*!\brief Frame resize denominator.
+ *
+ * The denominator for resize to use, assuming 8 as the numerator.
+ *
+ * Valid denominators are 8 - 16 for now.
+ */
+ unsigned int rc_resize_denominator;
+
+ /*!\brief Keyframe resize denominator.
+ *
+ * The denominator for resize to use, assuming 8 as the numerator.
+ *
+ * Valid denominators are 8 - 16 for now.
+ */
+ unsigned int rc_resize_kf_denominator;
+
+ /*!\brief Frame super-resolution scaling mode.
+ *
+ * Similar to spatial resampling, frame super-resolution integrates
+ * upscaling after the encode/decode process. Taking control of upscaling and
+ * using restoration filters should allow it to outperform normal resizing.
+ */
+ aom_superres_mode rc_superres_mode;
+
+ /*!\brief Frame super-resolution denominator.
+ *
+ * The denominator for superres to use. If fixed it will only change if the
+ * cumulative scale change over resizing and superres is greater than 1/2;
+ * this forces superres to reduce scaling.
+ *
+ * Valid denominators are 8 to 16.
+ *
+ * Used only by AOM_SUPERRES_FIXED.
+ */
+ unsigned int rc_superres_denominator;
+
+ /*!\brief Keyframe super-resolution denominator.
+ *
+ * The denominator for superres to use. If fixed it will only change if the
+ * cumulative scale change over resizing and superres is greater than 1/2;
+ * this forces superres to reduce scaling.
+ *
+ * Valid denominators are 8 - 16 for now.
+ */
+ unsigned int rc_superres_kf_denominator;
+
+ /*!\brief Frame super-resolution q threshold.
+ *
+ * The q level threshold after which superres is used.
+ * Valid values are 1 to 63.
+ *
+ * Used only by AOM_SUPERRES_QTHRESH
+ */
+ unsigned int rc_superres_qthresh;
+
+ /*!\brief Keyframe super-resolution q threshold.
+ *
+ * The q level threshold after which superres is used for key frames.
+ * Valid values are 1 to 63.
+ *
+ * Used only by AOM_SUPERRES_QTHRESH
+ */
+ unsigned int rc_superres_kf_qthresh;
+
+ /*!\brief Rate control algorithm to use.
+ *
+ * Indicates whether the end usage of this stream is to be streamed over
+ * a bandwidth constrained link, indicating that Constant Bit Rate (CBR)
+ * mode should be used, or whether it will be played back on a high
+ * bandwidth link, as from a local disk, where higher variations in
+ * bitrate are acceptable.
+ */
+ enum aom_rc_mode rc_end_usage;
+
+ /*!\brief Two-pass stats buffer.
+ *
+ * A buffer containing all of the stats packets produced in the first
+ * pass, concatenated.
+ */
+ aom_fixed_buf_t rc_twopass_stats_in;
+
+ /*!\brief first pass mb stats buffer.
+ *
+ * A buffer containing all of the first pass mb stats packets produced
+ * in the first pass, concatenated.
+ */
+ aom_fixed_buf_t rc_firstpass_mb_stats_in;
+
+ /*!\brief Target data rate
+ *
+ * Target bitrate to use for this stream, in kilobits per second.
+ */
+ unsigned int rc_target_bitrate;
+
+ /*
+ * quantizer settings
+ */
+
+ /*!\brief Minimum (Best Quality) Quantizer
+ *
+ * The quantizer is the most direct control over the quality of the
+ * encoded image. The range of valid values for the quantizer is codec
+ * specific. Consult the documentation for the codec to determine the
+ * values to use. To determine the range programmatically, call
+ * aom_codec_enc_config_default() with a usage value of 0.
+ */
+ unsigned int rc_min_quantizer;
+
+ /*!\brief Maximum (Worst Quality) Quantizer
+ *
+ * The quantizer is the most direct control over the quality of the
+ * encoded image. The range of valid values for the quantizer is codec
+ * specific. Consult the documentation for the codec to determine the
+ * values to use. To determine the range programmatically, call
+ * aom_codec_enc_config_default() with a usage value of 0.
+ */
+ unsigned int rc_max_quantizer;
+
+ /*
+ * bitrate tolerance
+ */
+
+ /*!\brief Rate control adaptation undershoot control
+ *
+ * This value, controls the tolerance of the VBR algorithm to undershoot
+ * and is used as a trigger threshold for more aggressive adaptation of Q.
+ *
+ * Valid values in the range 0-100.
+ */
+ unsigned int rc_undershoot_pct;
+
+ /*!\brief Rate control adaptation overshoot control
+ *
+ * This value, controls the tolerance of the VBR algorithm to overshoot
+ * and is used as a trigger threshold for more aggressive adaptation of Q.
+ *
+ * Valid values in the range 0-100.
+ */
+ unsigned int rc_overshoot_pct;
+
+ /*
+ * decoder buffer model parameters
+ */
+
+ /*!\brief Decoder Buffer Size
+ *
+ * This value indicates the amount of data that may be buffered by the
+ * decoding application. Note that this value is expressed in units of
+ * time (milliseconds). For example, a value of 5000 indicates that the
+ * client will buffer (at least) 5000ms worth of encoded data. Use the
+ * target bitrate (#rc_target_bitrate) to convert to bits/bytes, if
+ * necessary.
+ */
+ unsigned int rc_buf_sz;
+
+ /*!\brief Decoder Buffer Initial Size
+ *
+ * This value indicates the amount of data that will be buffered by the
+ * decoding application prior to beginning playback. This value is
+ * expressed in units of time (milliseconds). Use the target bitrate
+ * (#rc_target_bitrate) to convert to bits/bytes, if necessary.
+ */
+ unsigned int rc_buf_initial_sz;
+
+ /*!\brief Decoder Buffer Optimal Size
+ *
+ * This value indicates the amount of data that the encoder should try
+ * to maintain in the decoder's buffer. This value is expressed in units
+ * of time (milliseconds). Use the target bitrate (#rc_target_bitrate)
+ * to convert to bits/bytes, if necessary.
+ */
+ unsigned int rc_buf_optimal_sz;
+
+ /*
+ * 2 pass rate control parameters
+ */
+
+ /*!\brief Two-pass mode CBR/VBR bias
+ *
+ * Bias, expressed on a scale of 0 to 100, for determining target size
+ * for the current frame. The value 0 indicates the optimal CBR mode
+ * value should be used. The value 100 indicates the optimal VBR mode
+ * value should be used. Values in between indicate which way the
+ * encoder should "lean."
+ */
+ unsigned int rc_2pass_vbr_bias_pct;
+
+ /*!\brief Two-pass mode per-GOP minimum bitrate
+ *
+ * This value, expressed as a percentage of the target bitrate, indicates
+ * the minimum bitrate to be used for a single GOP (aka "section")
+ */
+ unsigned int rc_2pass_vbr_minsection_pct;
+
+ /*!\brief Two-pass mode per-GOP maximum bitrate
+ *
+ * This value, expressed as a percentage of the target bitrate, indicates
+ * the maximum bitrate to be used for a single GOP (aka "section")
+ */
+ unsigned int rc_2pass_vbr_maxsection_pct;
+
+ /*
+ * keyframing settings (kf)
+ */
+
+ /*!\brief Option to enable forward reference key frame
+ *
+ */
+ int fwd_kf_enabled;
+
+ /*!\brief Keyframe placement mode
+ *
+ * This value indicates whether the encoder should place keyframes at a
+ * fixed interval, or determine the optimal placement automatically
+ * (as governed by the #kf_min_dist and #kf_max_dist parameters)
+ */
+ enum aom_kf_mode kf_mode;
+
+ /*!\brief Keyframe minimum interval
+ *
+ * This value, expressed as a number of frames, prevents the encoder from
+ * placing a keyframe nearer than kf_min_dist to the previous keyframe. At
+ * least kf_min_dist frames non-keyframes will be coded before the next
+ * keyframe. Set kf_min_dist equal to kf_max_dist for a fixed interval.
+ */
+ unsigned int kf_min_dist;
+
+ /*!\brief Keyframe maximum interval
+ *
+ * This value, expressed as a number of frames, forces the encoder to code
+ * a keyframe if one has not been coded in the last kf_max_dist frames.
+ * A value of 0 implies all frames will be keyframes. Set kf_min_dist
+ * equal to kf_max_dist for a fixed interval.
+ */
+ unsigned int kf_max_dist;
+
+ /*!\brief sframe interval
+ *
+ * This value, expressed as a number of frames, forces the encoder to code
+ * an S-Frame every sframe_dist frames.
+ */
+ unsigned int sframe_dist;
+
+ /*!\brief sframe insertion mode
+ *
+ * This value must be set to 1 or 2, and tells the encoder how to insert
+ * S-Frames. It will only have an effect if sframe_dist != 0.
+ *
+ * If altref is enabled:
+ * - if sframe_mode == 1, the considered frame will be made into an
+ * S-Frame only if it is an altref frame
+ * - if sframe_mode == 2, the next altref frame will be made into an
+ * S-Frame.
+ *
+ * Otherwise: the considered frame will be made into an S-Frame.
+ */
+ unsigned int sframe_mode;
+
+ /*!\brief Tile coding mode
+ *
+ * This value indicates the tile coding mode.
+ * A value of 0 implies a normal non-large-scale tile coding. A value of 1
+ * implies a large-scale tile coding.
+ */
+ unsigned int large_scale_tile;
+
+ /*!\brief Monochrome mode
+ *
+ * If this is nonzero, the encoder will generate a monochrome stream
+ * with no chroma planes.
+ */
+ unsigned int monochrome;
+
+ /*!\brief full_still_picture_hdr
+ *
+ * If this is nonzero, the encoder will generate a full header even for
+ * still picture encoding. if zero, a reduced header is used for still
+ * picture. This flag has no effect when a regular video with more than
+ * a single frame is encoded.
+ */
+ unsigned int full_still_picture_hdr;
+
+ /*!\brief Bitstream syntax mode
+ *
+ * This value indicates the bitstream syntax mode.
+ * A value of 0 indicates bitstream is saved as Section 5 bitstream. A value
+ * of 1 indicates the bitstream is saved in Annex-B format
+ */
+ unsigned int save_as_annexb;
+
+ /*!\brief Number of explicit tile widths specified
+ *
+ * This value indicates the number of tile widths specified
+ * A value of 0 implies no tile widths are specified.
+ * Tile widths are given in the array tile_widths[]
+ */
+ int tile_width_count;
+
+ /*!\brief Number of explicit tile heights specified
+ *
+ * This value indicates the number of tile heights specified
+ * A value of 0 implies no tile heights are specified.
+ * Tile heights are given in the array tile_heights[]
+ */
+ int tile_height_count;
+
+/*!\brief Maximum number of tile widths in tile widths array
+ *
+ * This define gives the maximum number of elements in the tile_widths array.
+ */
+#define MAX_TILE_WIDTHS 64 // maximum tile width array length
+
+ /*!\brief Array of specified tile widths
+ *
+ * This array specifies tile widths (and may be empty)
+ * The number of widths specified is given by tile_width_count
+ */
+ int tile_widths[MAX_TILE_WIDTHS];
+
+/*!\brief Maximum number of tile heights in tile heights array.
+ *
+ * This define gives the maximum number of elements in the tile_heights array.
+ */
+#define MAX_TILE_HEIGHTS 64 // maximum tile height array length
+
+ /*!\brief Array of specified tile heights
+ *
+ * This array specifies tile heights (and may be empty)
+ * The number of heights specified is given by tile_height_count
+ */
+ int tile_heights[MAX_TILE_HEIGHTS];
+
+ /*!\brief Whether encoder should use fixed QP offsets.
+ *
+ * If a value of 1 is provided, encoder will use fixed QP offsets for frames
+ * at different levels of the pyramid.
+ * If a value of 0 is provided, encoder will NOT use fixed QP offsets.
+ * Note: This option is only relevant for --end-usage=q.
+ */
+ unsigned int use_fixed_qp_offsets;
+
+ /*!\brief Deprecated and ignored. DO NOT USE.
+ *
+ * TODO(aomedia:3269): Remove fixed_qp_offsets in libaom v4.0.0.
+ */
+ int fixed_qp_offsets[5];
+
+ /*!\brief Options defined per config file
+ *
+ */
+ cfg_options_t encoder_cfg;
+} aom_codec_enc_cfg_t; /**< alias for struct aom_codec_enc_cfg */
+
+/*!\brief Initialize an encoder instance
+ *
+ * Initializes a encoder context using the given interface. Applications
+ * should call the aom_codec_enc_init convenience macro instead of this
+ * function directly, to ensure that the ABI version number parameter
+ * is properly initialized.
+ *
+ * If the library was configured with -DCONFIG_MULTITHREAD=0, this call
+ * is not thread safe and should be guarded with a lock if being used
+ * in a multithreaded context.
+ *
+ * \param[in] ctx Pointer to this instance's context.
+ * \param[in] iface Pointer to the algorithm interface to use.
+ * \param[in] cfg Configuration to use, if known.
+ * \param[in] flags Bitfield of AOM_CODEC_USE_* flags
+ * \param[in] ver ABI version number. Must be set to
+ * AOM_ENCODER_ABI_VERSION
+ * \retval #AOM_CODEC_OK
+ * The decoder algorithm initialized.
+ * \retval #AOM_CODEC_MEM_ERROR
+ * Memory allocation failed.
+ */
+aom_codec_err_t aom_codec_enc_init_ver(aom_codec_ctx_t *ctx,
+ aom_codec_iface_t *iface,
+ const aom_codec_enc_cfg_t *cfg,
+ aom_codec_flags_t flags, int ver);
+
+/*!\brief Convenience macro for aom_codec_enc_init_ver()
+ *
+ * Ensures the ABI version parameter is properly set.
+ */
+#define aom_codec_enc_init(ctx, iface, cfg, flags) \
+ aom_codec_enc_init_ver(ctx, iface, cfg, flags, AOM_ENCODER_ABI_VERSION)
+
+/*!\brief Get the default configuration for a usage.
+ *
+ * Initializes an encoder configuration structure with default values. Supports
+ * the notion of "usages" so that an algorithm may offer different default
+ * settings depending on the user's intended goal. This function \ref SHOULD
+ * be called by all applications to initialize the configuration structure
+ * before specializing the configuration with application specific values.
+ *
+ * \param[in] iface Pointer to the algorithm interface to use.
+ * \param[out] cfg Configuration buffer to populate.
+ * \param[in] usage Algorithm specific usage value. For AV1, must be
+ * set to AOM_USAGE_GOOD_QUALITY (0),
+ * AOM_USAGE_REALTIME (1), or AOM_USAGE_ALL_INTRA (2).
+ *
+ * \retval #AOM_CODEC_OK
+ * The configuration was populated.
+ * \retval #AOM_CODEC_INCAPABLE
+ * Interface is not an encoder interface.
+ * \retval #AOM_CODEC_INVALID_PARAM
+ * A parameter was NULL, or the usage value was not recognized.
+ */
+aom_codec_err_t aom_codec_enc_config_default(aom_codec_iface_t *iface,
+ aom_codec_enc_cfg_t *cfg,
+ unsigned int usage);
+
+/*!\brief Set or change configuration
+ *
+ * Reconfigures an encoder instance according to the given configuration.
+ *
+ * \param[in] ctx Pointer to this instance's context
+ * \param[in] cfg Configuration buffer to use
+ *
+ * \retval #AOM_CODEC_OK
+ * The configuration was populated.
+ * \retval #AOM_CODEC_INCAPABLE
+ * Interface is not an encoder interface.
+ * \retval #AOM_CODEC_INVALID_PARAM
+ * A parameter was NULL, or the usage value was not recognized.
+ */
+aom_codec_err_t aom_codec_enc_config_set(aom_codec_ctx_t *ctx,
+ const aom_codec_enc_cfg_t *cfg);
+
+/*!\brief Get global stream headers
+ *
+ * Retrieves a stream level global header packet, if supported by the codec.
+ * Calls to this function should be deferred until all configuration information
+ * has been passed to libaom. Otherwise the global header data may be
+ * invalidated by additional configuration changes.
+ *
+ * The AV1 implementation of this function returns an OBU. The OBU returned is
+ * in Low Overhead Bitstream Format. Specifically, the obu_has_size_field bit is
+ * set, and the buffer contains the obu_size field for the returned OBU.
+ *
+ * \param[in] ctx Pointer to this instance's context
+ *
+ * \retval NULL
+ * Encoder does not support global header, or an error occurred while
+ * generating the global header.
+ *
+ * \retval Non-NULL
+ * Pointer to buffer containing global header packet. The caller owns the
+ * memory associated with this buffer, and must free the 'buf' member of the
+ * aom_fixed_buf_t as well as the aom_fixed_buf_t pointer. Memory returned
+ * must be freed via call to free().
+ */
+aom_fixed_buf_t *aom_codec_get_global_headers(aom_codec_ctx_t *ctx);
+
+/*!\brief usage parameter analogous to AV1 GOOD QUALITY mode. */
+#define AOM_USAGE_GOOD_QUALITY (0)
+/*!\brief usage parameter analogous to AV1 REALTIME mode. */
+#define AOM_USAGE_REALTIME (1)
+/*!\brief usage parameter analogous to AV1 all intra mode. */
+#define AOM_USAGE_ALL_INTRA (2)
+
+/*!\brief Encode a frame
+ *
+ * Encodes a video frame at the given "presentation time." The presentation
+ * time stamp (PTS) \ref MUST be strictly increasing.
+ *
+ * When the last frame has been passed to the encoder, this function should
+ * continue to be called in a loop, with the img parameter set to NULL. This
+ * will signal the end-of-stream condition to the encoder and allow it to
+ * encode any held buffers. Encoding is complete when aom_codec_encode() is
+ * called with img set to NULL and aom_codec_get_cx_data() returns no data.
+ *
+ * \param[in] ctx Pointer to this instance's context
+ * \param[in] img Image data to encode, NULL to flush.
+ * Encoding sample values outside the range
+ * [0..(1<bit_depth)-1] is undefined behavior.
+ * \param[in] pts Presentation time stamp, in timebase units. If img
+ * is NULL, pts is ignored.
+ * \param[in] duration Duration to show frame, in timebase units. If img
+ * is not NULL, duration must be nonzero. If img is
+ * NULL, duration is ignored.
+ * \param[in] flags Flags to use for encoding this frame.
+ *
+ * \retval #AOM_CODEC_OK
+ * The configuration was populated.
+ * \retval #AOM_CODEC_INCAPABLE
+ * Interface is not an encoder interface.
+ * \retval #AOM_CODEC_INVALID_PARAM
+ * A parameter was NULL, the image format is unsupported, etc.
+ */
+aom_codec_err_t aom_codec_encode(aom_codec_ctx_t *ctx, const aom_image_t *img,
+ aom_codec_pts_t pts, unsigned long duration,
+ aom_enc_frame_flags_t flags);
+
+/*!\brief Set compressed data output buffer
+ *
+ * Sets the buffer that the codec should output the compressed data
+ * into. This call effectively sets the buffer pointer returned in the
+ * next AOM_CODEC_CX_FRAME_PKT packet. Subsequent packets will be
+ * appended into this buffer. The buffer is preserved across frames,
+ * so applications must periodically call this function after flushing
+ * the accumulated compressed data to disk or to the network to reset
+ * the pointer to the buffer's head.
+ *
+ * `pad_before` bytes will be skipped before writing the compressed
+ * data, and `pad_after` bytes will be appended to the packet. The size
+ * of the packet will be the sum of the size of the actual compressed
+ * data, pad_before, and pad_after. The padding bytes will be preserved
+ * (not overwritten).
+ *
+ * Note that calling this function does not guarantee that the returned
+ * compressed data will be placed into the specified buffer. In the
+ * event that the encoded data will not fit into the buffer provided,
+ * the returned packet \ref MAY point to an internal buffer, as it would
+ * if this call were never used. In this event, the output packet will
+ * NOT have any padding, and the application must free space and copy it
+ * to the proper place. This is of particular note in configurations
+ * that may output multiple packets for a single encoded frame (e.g., lagged
+ * encoding) or if the application does not reset the buffer periodically.
+ *
+ * Applications may restore the default behavior of the codec providing
+ * the compressed data buffer by calling this function with a NULL
+ * buffer.
+ *
+ * Applications \ref MUSTNOT call this function during iteration of
+ * aom_codec_get_cx_data().
+ *
+ * \param[in] ctx Pointer to this instance's context
+ * \param[in] buf Buffer to store compressed data into
+ * \param[in] pad_before Bytes to skip before writing compressed data
+ * \param[in] pad_after Bytes to skip after writing compressed data
+ *
+ * \retval #AOM_CODEC_OK
+ * The buffer was set successfully.
+ * \retval #AOM_CODEC_INVALID_PARAM
+ * A parameter was NULL, the image format is unsupported, etc.
+ */
+aom_codec_err_t aom_codec_set_cx_data_buf(aom_codec_ctx_t *ctx,
+ const aom_fixed_buf_t *buf,
+ unsigned int pad_before,
+ unsigned int pad_after);
+
+/*!\brief Encoded data iterator
+ *
+ * Iterates over a list of data packets to be passed from the encoder to the
+ * application. The different kinds of packets available are enumerated in
+ * #aom_codec_cx_pkt_kind.
+ *
+ * #AOM_CODEC_CX_FRAME_PKT packets should be passed to the application's
+ * muxer. Multiple compressed frames may be in the list.
+ * #AOM_CODEC_STATS_PKT packets should be appended to a global buffer.
+ *
+ * The application \ref MUST silently ignore any packet kinds that it does
+ * not recognize or support.
+ *
+ * The data buffers returned from this function are only guaranteed to be
+ * valid until the application makes another call to any aom_codec_* function.
+ *
+ * \param[in] ctx Pointer to this instance's context
+ * \param[in,out] iter Iterator storage, initialized to NULL
+ *
+ * \return Returns a pointer to an output data packet (compressed frame data,
+ * two-pass statistics, etc.) or NULL to signal end-of-list.
+ *
+ */
+const aom_codec_cx_pkt_t *aom_codec_get_cx_data(aom_codec_ctx_t *ctx,
+ aom_codec_iter_t *iter);
+
+/*!\brief Get Preview Frame
+ *
+ * Returns an image that can be used as a preview. Shows the image as it would
+ * exist at the decompressor. The application \ref MUST NOT write into this
+ * image buffer.
+ *
+ * \param[in] ctx Pointer to this instance's context
+ *
+ * \return Returns a pointer to a preview image, or NULL if no image is
+ * available.
+ *
+ */
+const aom_image_t *aom_codec_get_preview_frame(aom_codec_ctx_t *ctx);
+
+/*!@} - end defgroup encoder*/
+#ifdef __cplusplus
+}
+#endif
+#endif // AOM_AOM_AOM_ENCODER_H_
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_external_partition.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_external_partition.h
new file mode 100644
index 0000000..55c59a5
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_external_partition.h
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2021, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+#ifndef AOM_AOM_AOM_EXTERNAL_PARTITION_H_
+#define AOM_AOM_AOM_EXTERNAL_PARTITION_H_
+
+/*!\defgroup aom_encoder AOMedia AOM/AV1 Encoder
+ * \ingroup aom
+ *
+ * @{
+ */
+#include
+
+/*!\file
+ * \brief Provides function pointer definitions for the external partition.
+ *
+ * \note The external partition API should be considered experimental. Until the
+ * external partition API is declared stable, breaking changes may be made to
+ * this API in a future libaom release.
+ */
+
+/*!\brief Current ABI version number
+ *
+ * \internal
+ * If this file is altered in any way that changes the ABI, this value
+ * must be bumped. Examples include, but are not limited to, changing
+ * types, removing or reassigning enums, adding/removing/rearranging
+ * fields to structures.
+ */
+#define AOM_EXT_PART_ABI_VERSION 8
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!\brief Abstract external partition model handler
+ */
+typedef void *aom_ext_part_model_t;
+
+/*!\brief Number of features to determine whether to skip partition none and
+ * do partition split directly. The same as "FEATURE_SIZE_SMS_SPLIT".
+ */
+#define AOM_EXT_PART_SIZE_DIRECT_SPLIT 17
+
+/*!\brief Number of features to use simple motion search to prune out
+ * rectangular partition in some direction. The same as
+ * "FEATURE_SIZE_SMS_PRUNE_PART".
+ */
+#define AOM_EXT_PART_SIZE_PRUNE_PART 25
+
+/*!\brief Number of features to prune split and rectangular partition
+ * after PARTITION_NONE.
+ */
+#define AOM_EXT_PART_SIZE_PRUNE_NONE 4
+
+/*!\brief Number of features to terminates partition after partition none using
+ * simple_motion_search features and the rate, distortion, and rdcost of
+ * PARTITION_NONE. The same as "FEATURE_SIZE_SMS_TERM_NONE".
+ */
+#define AOM_EXT_PART_SIZE_TERM_NONE 28
+
+/*!\brief Number of features to terminates partition after partition split.
+ */
+#define AOM_EXT_PART_SIZE_TERM_SPLIT 31
+
+/*!\brief Number of features to prune rectangular partition using stats
+ * collected after partition split.
+ */
+#define AOM_EXT_PART_SIZE_PRUNE_RECT 9
+
+/*!\brief Number of features to prune AB partition using stats
+ * collected after rectangular partition..
+ */
+#define AOM_EXT_PART_SIZE_PRUNE_AB 10
+
+/*!\brief Number of features to prune 4-way partition using stats
+ * collected after AB partition.
+ */
+#define AOM_EXT_PART_SIZE_PRUNE_4_WAY 18
+
+/*!\brief Decision mode of the external partition model.
+ * AOM_EXT_PART_WHOLE_TREE: the external partition model should provide the
+ * whole partition tree for the superblock.
+ *
+ * AOM_EXT_PART_RECURSIVE: the external partition model provides the partition
+ * decision of the current block only. The decision process starts from
+ * the superblock size, down to the smallest block size (4x4) recursively.
+ */
+typedef enum aom_ext_part_decision_mode {
+ AOM_EXT_PART_WHOLE_TREE = 0,
+ AOM_EXT_PART_RECURSIVE = 1,
+} aom_ext_part_decision_mode_t;
+
+/*!\brief Config information sent to the external partition model.
+ *
+ * For example, the maximum superblock size determined by the sequence header.
+ */
+typedef struct aom_ext_part_config {
+ int superblock_size; ///< super block size (either 64x64 or 128x128)
+} aom_ext_part_config_t;
+
+/*!\brief Features pass to the external model to make partition decisions.
+ * Specifically, features collected before NONE partition.
+ * Features "f" are used to determine:
+ * partition_none_allowed, partition_horz_allowed, partition_vert_allowed,
+ * do_rectangular_split, do_square_split
+ * Features "f_part2" are used to determine:
+ * prune_horz, prune_vert.
+ */
+typedef struct aom_partition_features_before_none {
+ /*! features to determine whether skip partition none and do split directly */
+ float f[AOM_EXT_PART_SIZE_DIRECT_SPLIT];
+ /*! features to determine whether to prune rectangular partition */
+ float f_part2[AOM_EXT_PART_SIZE_PRUNE_PART];
+} aom_partition_features_before_none_t;
+
+/*!\brief Features pass to the external model to make partition decisions.
+ * Specifically, features collected after NONE partition.
+ */
+typedef struct aom_partition_features_none {
+ /*! features to prune split and rectangular partition */
+ float f[AOM_EXT_PART_SIZE_PRUNE_NONE];
+ /*! features to determine termination of partition */
+ float f_terminate[AOM_EXT_PART_SIZE_TERM_NONE];
+} aom_partition_features_none_t;
+
+/*!\brief Features pass to the external model to make partition decisions.
+ * Specifically, features collected after SPLIT partition.
+ */
+typedef struct aom_partition_features_split {
+ /*! features to determine termination of partition */
+ float f_terminate[AOM_EXT_PART_SIZE_TERM_SPLIT];
+ /*! features to determine pruning rect partition */
+ float f_prune_rect[AOM_EXT_PART_SIZE_PRUNE_RECT];
+} aom_partition_features_split_t;
+
+/*!\brief Features pass to the external model to make partition decisions.
+ * Specifically, features collected after RECTANGULAR partition.
+ */
+typedef struct aom_partition_features_rect {
+ /*! features to determine pruning AB partition */
+ float f[AOM_EXT_PART_SIZE_PRUNE_AB];
+} aom_partition_features_rect_t;
+
+/*!\brief Features pass to the external model to make partition decisions.
+ * Specifically, features collected after AB partition: HORZ_A, HORZ_B, VERT_A,
+ * VERT_B.
+ */
+typedef struct aom_partition_features_ab {
+ /*! features to determine pruning 4-way partition */
+ float f[AOM_EXT_PART_SIZE_PRUNE_4_WAY];
+} aom_partition_features_ab_t;
+
+/*!\brief Feature id to tell the external model the current stage in partition
+ * pruning and what features to use to make decisions accordingly.
+ */
+typedef enum {
+ AOM_EXT_PART_FEATURE_BEFORE_NONE,
+ AOM_EXT_PART_FEATURE_BEFORE_NONE_PART2,
+ AOM_EXT_PART_FEATURE_AFTER_NONE,
+ AOM_EXT_PART_FEATURE_AFTER_NONE_PART2,
+ AOM_EXT_PART_FEATURE_AFTER_SPLIT,
+ AOM_EXT_PART_FEATURE_AFTER_SPLIT_PART2,
+ AOM_EXT_PART_FEATURE_AFTER_RECT,
+ AOM_EXT_PART_FEATURE_AFTER_AB
+} AOM_EXT_PART_FEATURE_ID;
+
+/*!\brief Features collected from the tpl process.
+ *
+ * The tpl process collects information that help measure the inter-frame
+ * dependency.
+ * The tpl process is computed in the unit of tpl_bsize_1d (16x16).
+ * Therefore, the max number of units inside a superblock is
+ * 128x128 / (16x16) = 64. Change it if the tpl process changes.
+ */
+typedef struct aom_sb_tpl_features {
+ int available; ///< If tpl stats are available
+ int tpl_unit_length; ///< The block length of tpl process
+ int num_units; ///< The number of units inside the current superblock
+ int64_t intra_cost[64]; ///< The intra cost of each unit
+ int64_t inter_cost[64]; ///< The inter cost of each unit
+ int64_t mc_dep_cost[64]; ///< The motion compensated dependency cost
+} aom_sb_tpl_features_t;
+
+/*!\brief Features collected from the simple motion process.
+ *
+ * The simple motion process collects information by applying motion compensated
+ * prediction on each block.
+ * The block size is 16x16, which could be changed. If it is changed, update
+ * comments and the array size here.
+ */
+typedef struct aom_sb_simple_motion_features {
+ int unit_length; ///< The block length of the simple motion process
+ int num_units; ///< The number of units inside the current superblock
+ int block_sse[64]; ///< Sum of squared error of each unit
+ int block_var[64]; ///< Variance of each unit
+} aom_sb_simple_motion_features_t;
+
+/*!\brief Features of each super block.
+ *
+ * Features collected for each super block before partition search.
+ */
+typedef struct aom_sb_features {
+ /*! Features from motion search */
+ aom_sb_simple_motion_features_t motion_features;
+ /*! Features from tpl process */
+ aom_sb_tpl_features_t tpl_features;
+} aom_sb_features_t;
+
+/*!\brief Features pass to the external model to make partition decisions.
+ *
+ * The encoder sends these features to the external model through
+ * "func()" defined in .....
+ *
+ * NOTE: new member variables may be added to this structure in the future.
+ * Once new features are finalized, bump the major version of libaom.
+ */
+typedef struct aom_partition_features {
+ // Features for the current supervised multi-stage ML model.
+ /*! Feature ID to indicate active features */
+ AOM_EXT_PART_FEATURE_ID id;
+ /*! Features collected before NONE partition */
+ aom_partition_features_before_none_t before_part_none;
+ /*! Features collected after NONE partition */
+ aom_partition_features_none_t after_part_none;
+ /*! Features collected after SPLIT partition */
+ aom_partition_features_split_t after_part_split;
+ /*! Features collected after RECTANGULAR partition */
+ aom_partition_features_rect_t after_part_rect;
+ /*! Features collected after AB partition */
+ aom_partition_features_ab_t after_part_ab;
+
+ // Features for a new ML model.
+ aom_sb_features_t sb_features; ///< Features collected for the super block
+ int mi_row; ///< Mi_row position of the block
+ int mi_col; ///< Mi_col position of the block
+ int frame_width; ///< Frame width
+ int frame_height; ///< Frame height
+ int block_size; ///< As "BLOCK_SIZE" in av1/common/enums.h
+ /*!
+ * Valid partition types. A bitmask is used. "1" represents the
+ * corresponding type is vaild. The bitmask follows the enum order for
+ * PARTITION_TYPE in "enums.h" to represent one partition type at a bit.
+ * For example, 0x01 stands for only PARTITION_NONE is valid,
+ * 0x09 (00...001001) stands for PARTITION_NONE and PARTITION_SPLIT are valid.
+ */
+ int valid_partition_types;
+ int update_type; ///< Frame update type, defined in ratectrl.h
+ int qindex; ///< Quantization index, range: [0, 255]
+ int rdmult; ///< Rate-distortion multiplier
+ int pyramid_level; ///< The level of this frame in the hierarchical structure
+ int has_above_block; ///< Has above neighbor block
+ int above_block_width; ///< Width of the above block, -1 if not exist
+ int above_block_height; ///< Height of the above block, -1 if not exist
+ int has_left_block; ///< Has left neighbor block
+ int left_block_width; ///< Width of the left block, -1 if not exist
+ int left_block_height; ///< Height of the left block, -1 if not exist
+ /*!
+ * The following parameters are collected from applying simple motion search.
+ * Sum of squared error (SSE) and variance of motion compensated residual
+ * are good indicators of block partitioning.
+ * If a block is a square, we also apply motion search for its 4 sub blocks.
+ * If not a square, their values are -1.
+ * If a block is able to split horizontally, we apply motion search and get
+ * stats for horizontal blocks. If not, their values are -1.
+ * If a block is able to split vertically, we apply motion search and get
+ * stats for vertical blocks. If not, their values are -1.
+ */
+ unsigned int block_sse; ///< SSE of motion compensated residual
+ unsigned int block_var; ///< Variance of motion compensated residual
+ unsigned int sub_block_sse[4]; ///< SSE of sub blocks.
+ unsigned int sub_block_var[4]; ///< Variance of sub blocks.
+ unsigned int horz_block_sse[2]; ///< SSE of horz sub blocks
+ unsigned int horz_block_var[2]; ///< Variance of horz sub blocks
+ unsigned int vert_block_sse[2]; ///< SSE of vert sub blocks
+ unsigned int vert_block_var[2]; ///< Variance of vert sub blocks
+ /*!
+ * The following parameters are calculated from tpl model.
+ * If tpl model is not available, their values are -1.
+ */
+ int64_t tpl_intra_cost; ///< Intra cost, ref to "TplDepStats" in tpl_model.h
+ int64_t tpl_inter_cost; ///< Inter cost in tpl model
+ int64_t tpl_mc_dep_cost; ///< Motion compensated dependency cost in tpl model
+} aom_partition_features_t;
+
+/*!\brief Partition decisions received from the external model.
+ *
+ * The encoder receives partition decisions and encodes the superblock
+ * with the given partition type.
+ * The encoder receives it from "func()" define in ....
+ *
+ * NOTE: new member variables may be added to this structure in the future.
+ * Once new features are finalized, bump the major version of libaom.
+ */
+typedef struct aom_partition_decision {
+ // Decisions for directly set partition types
+ int is_final_decision; ///< The flag whether it's the final decision
+ int num_nodes; ///< The number of leaf nodes
+ int partition_decision[2048]; ///< Partition decisions
+ int current_decision; ///< Partition decision for the current block
+
+ // Decisions for partition type pruning
+ int terminate_partition_search; ///< Terminate further partition search
+ int partition_none_allowed; ///< Allow partition none type
+ int partition_rect_allowed[2]; ///< Allow rectangular partitions
+ int do_rectangular_split; ///< Try rectangular split partition
+ int do_square_split; ///< Try square split partition
+ int prune_rect_part[2]; ///< Prune rectangular partition
+ int horza_partition_allowed; ///< Allow HORZ_A partitioin
+ int horzb_partition_allowed; ///< Allow HORZ_B partitioin
+ int verta_partition_allowed; ///< Allow VERT_A partitioin
+ int vertb_partition_allowed; ///< Allow VERT_B partitioin
+ int partition_horz4_allowed; ///< Allow HORZ4 partition
+ int partition_vert4_allowed; ///< Allow VERT4 partition
+} aom_partition_decision_t;
+
+/*!\brief Encoding stats for the given partition decision.
+ *
+ * The encoding stats collected by encoding the superblock with the
+ * given partition types.
+ * The encoder sends the stats to the external model for training
+ * or inference though "func()" defined in ....
+ */
+typedef struct aom_partition_stats {
+ int rate; ///< Rate cost of the block
+ int64_t dist; ///< Distortion of the block
+ int64_t rdcost; ///< Rate-distortion cost of the block
+} aom_partition_stats_t;
+
+/*!\brief Enum for return status.
+ */
+typedef enum aom_ext_part_status {
+ AOM_EXT_PART_OK = 0, ///< Status of success
+ AOM_EXT_PART_ERROR = 1, ///< Status of failure
+ AOM_EXT_PART_TEST = 2, ///< Status used for tests
+} aom_ext_part_status_t;
+
+/*!\brief Callback of creating an external partition model.
+ *
+ * The callback is invoked by the encoder to create an external partition
+ * model.
+ *
+ * \param[in] priv Callback's private data
+ * \param[in] part_config Config information pointer for model creation
+ * \param[out] ext_part_model Pointer to the model
+ */
+typedef aom_ext_part_status_t (*aom_ext_part_create_model_fn_t)(
+ void *priv, const aom_ext_part_config_t *part_config,
+ aom_ext_part_model_t *ext_part_model);
+
+/*!\brief Callback of sending features to the external partition model.
+ *
+ * The callback is invoked by the encoder to send features to the external
+ * partition model.
+ *
+ * \param[in] ext_part_model The external model
+ * \param[in] part_features Pointer to the features
+ */
+typedef aom_ext_part_status_t (*aom_ext_part_send_features_fn_t)(
+ aom_ext_part_model_t ext_part_model,
+ const aom_partition_features_t *part_features);
+
+/*!\brief Callback of receiving partition decisions from the external
+ * partition model.
+ *
+ * The callback is invoked by the encoder to receive partition decisions from
+ * the external partition model.
+ *
+ * \param[in] ext_part_model The external model
+ * \param[in] ext_part_decision Pointer to the partition decisions
+ */
+typedef aom_ext_part_status_t (*aom_ext_part_get_decision_fn_t)(
+ aom_ext_part_model_t ext_part_model,
+ aom_partition_decision_t *ext_part_decision);
+
+/*!\brief Callback of sending stats to the external partition model.
+ *
+ * The callback is invoked by the encoder to send encoding stats to
+ * the external partition model.
+ *
+ * \param[in] ext_part_model The external model
+ * \param[in] ext_part_stats Pointer to the encoding stats
+ */
+typedef aom_ext_part_status_t (*aom_ext_part_send_partition_stats_fn_t)(
+ aom_ext_part_model_t ext_part_model,
+ const aom_partition_stats_t *ext_part_stats);
+
+/*!\brief Callback of deleting the external partition model.
+ *
+ * The callback is invoked by the encoder to delete the external partition
+ * model.
+ *
+ * \param[in] ext_part_model The external model
+ */
+typedef aom_ext_part_status_t (*aom_ext_part_delete_model_fn_t)(
+ aom_ext_part_model_t ext_part_model);
+
+/*!\brief Callback function set for external partition model.
+ *
+ * Uses can enable external partition model by registering a set of
+ * callback functions with the flag: AV1E_SET_EXTERNAL_PARTITION_MODEL
+ */
+typedef struct aom_ext_part_funcs {
+ /*!
+ * Create an external partition model.
+ */
+ aom_ext_part_create_model_fn_t create_model;
+
+ /*!
+ * Send features to the external partition model to make partition decisions.
+ */
+ aom_ext_part_send_features_fn_t send_features;
+
+ /*!
+ * Get partition decisions from the external partition model.
+ */
+ aom_ext_part_get_decision_fn_t get_partition_decision;
+
+ /*!
+ * Send stats of the current partition to the external model.
+ */
+ aom_ext_part_send_partition_stats_fn_t send_partition_stats;
+
+ /*!
+ * Delete the external partition model.
+ */
+ aom_ext_part_delete_model_fn_t delete_model;
+
+ /*!
+ * The decision mode of the model.
+ */
+ aom_ext_part_decision_mode_t decision_mode;
+
+ /*!
+ * Private data for the external partition model.
+ */
+ void *priv;
+} aom_ext_part_funcs_t;
+
+/*!@} - end defgroup aom_encoder*/
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // AOM_AOM_AOM_EXTERNAL_PARTITION_H_
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_frame_buffer.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_frame_buffer.h
new file mode 100644
index 0000000..0e80373
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_frame_buffer.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+#ifndef AOM_AOM_AOM_FRAME_BUFFER_H_
+#define AOM_AOM_AOM_FRAME_BUFFER_H_
+
+/*!\file
+ * \brief Describes the decoder external frame buffer interface.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "aom/aom_integer.h"
+
+/*!\brief The maximum number of work buffers used by libaom.
+ * Support maximum 4 threads to decode video in parallel.
+ * Each thread will use one work buffer.
+ * TODO(hkuang): Add support to set number of worker threads dynamically.
+ */
+#define AOM_MAXIMUM_WORK_BUFFERS 8
+
+/*!\brief The maximum number of reference buffers that a AV1 encoder may use.
+ */
+#define AOM_MAXIMUM_REF_BUFFERS 8
+
+/*!\brief External frame buffer
+ *
+ * This structure holds allocated frame buffers used by the decoder.
+ */
+typedef struct aom_codec_frame_buffer {
+ uint8_t *data; /**< Pointer to the data buffer */
+ size_t size; /**< Size of data in bytes */
+ void *priv; /**< Frame's private data */
+} aom_codec_frame_buffer_t;
+
+/*!\brief get frame buffer callback prototype
+ *
+ * This callback is invoked by the decoder to retrieve data for the frame
+ * buffer in order for the decode call to complete. The callback must
+ * allocate at least min_size in bytes and assign it to fb->data. The callback
+ * must zero out all the data allocated. Then the callback must set fb->size
+ * to the allocated size. The application does not need to align the allocated
+ * data. The callback is triggered when the decoder needs a frame buffer to
+ * decode a compressed image into. This function may be called more than once
+ * for every call to aom_codec_decode. The application may set fb->priv to
+ * some data which will be passed back in the aom_image_t and the release
+ * function call. |fb| is guaranteed to not be NULL. On success the callback
+ * must return 0. Any failure the callback must return a value less than 0.
+ *
+ * \param[in] priv Callback's private data
+ * \param[in] min_size Size in bytes needed by the buffer
+ * \param[in,out] fb Pointer to aom_codec_frame_buffer_t
+ */
+typedef int (*aom_get_frame_buffer_cb_fn_t)(void *priv, size_t min_size,
+ aom_codec_frame_buffer_t *fb);
+
+/*!\brief release frame buffer callback prototype
+ *
+ * This callback is invoked by the decoder when the frame buffer is not
+ * referenced by any other buffers. |fb| is guaranteed to not be NULL. On
+ * success the callback must return 0. Any failure the callback must return
+ * a value less than 0.
+ *
+ * \param[in] priv Callback's private data
+ * \param[in] fb Pointer to aom_codec_frame_buffer_t
+ */
+typedef int (*aom_release_frame_buffer_cb_fn_t)(void *priv,
+ aom_codec_frame_buffer_t *fb);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // AOM_AOM_AOM_FRAME_BUFFER_H_
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_image.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_image.h
new file mode 100644
index 0000000..d5f0c08
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_image.h
@@ -0,0 +1,448 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+/*!\file
+ * \brief Describes the aom image descriptor and associated operations
+ *
+ */
+#ifndef AOM_AOM_AOM_IMAGE_H_
+#define AOM_AOM_AOM_IMAGE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "aom/aom_integer.h"
+
+/*!\brief Current ABI version number
+ *
+ * \internal
+ * If this file is altered in any way that changes the ABI, this value
+ * must be bumped. Examples include, but are not limited to, changing
+ * types, removing or reassigning enums, adding/removing/rearranging
+ * fields to structures
+ */
+#define AOM_IMAGE_ABI_VERSION (9) /**<\hideinitializer*/
+
+#define AOM_IMG_FMT_PLANAR 0x100 /**< Image is a planar format. */
+#define AOM_IMG_FMT_UV_FLIP 0x200 /**< V plane precedes U in memory. */
+/** 0x400 used to signal alpha channel, skipping for backwards compatibility. */
+#define AOM_IMG_FMT_HIGHBITDEPTH 0x800 /**< Image uses 16bit framebuffer. */
+
+/*!\brief List of supported image formats */
+typedef enum aom_img_fmt {
+ AOM_IMG_FMT_NONE,
+ AOM_IMG_FMT_YV12 =
+ AOM_IMG_FMT_PLANAR | AOM_IMG_FMT_UV_FLIP | 1, /**< planar YVU */
+ AOM_IMG_FMT_I420 = AOM_IMG_FMT_PLANAR | 2,
+ AOM_IMG_FMT_AOMYV12 = AOM_IMG_FMT_PLANAR | AOM_IMG_FMT_UV_FLIP |
+ 3, /** < planar 4:2:0 format with aom color space */
+ AOM_IMG_FMT_AOMI420 = AOM_IMG_FMT_PLANAR | 4,
+ AOM_IMG_FMT_I422 = AOM_IMG_FMT_PLANAR | 5,
+ AOM_IMG_FMT_I444 = AOM_IMG_FMT_PLANAR | 6,
+/*!\brief Allows detection of the presence of AOM_IMG_FMT_NV12 at compile time.
+ */
+#define AOM_HAVE_IMG_FMT_NV12 1
+ AOM_IMG_FMT_NV12 =
+ AOM_IMG_FMT_PLANAR | 7, /**< 4:2:0 with U and V interleaved */
+ AOM_IMG_FMT_I42016 = AOM_IMG_FMT_I420 | AOM_IMG_FMT_HIGHBITDEPTH,
+ AOM_IMG_FMT_YV1216 = AOM_IMG_FMT_YV12 | AOM_IMG_FMT_HIGHBITDEPTH,
+ AOM_IMG_FMT_I42216 = AOM_IMG_FMT_I422 | AOM_IMG_FMT_HIGHBITDEPTH,
+ AOM_IMG_FMT_I44416 = AOM_IMG_FMT_I444 | AOM_IMG_FMT_HIGHBITDEPTH,
+} aom_img_fmt_t; /**< alias for enum aom_img_fmt */
+
+/*!\brief List of supported color primaries */
+typedef enum aom_color_primaries {
+ AOM_CICP_CP_RESERVED_0 = 0, /**< For future use */
+ AOM_CICP_CP_BT_709 = 1, /**< BT.709 */
+ AOM_CICP_CP_UNSPECIFIED = 2, /**< Unspecified */
+ AOM_CICP_CP_RESERVED_3 = 3, /**< For future use */
+ AOM_CICP_CP_BT_470_M = 4, /**< BT.470 System M (historical) */
+ AOM_CICP_CP_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */
+ AOM_CICP_CP_BT_601 = 6, /**< BT.601 */
+ AOM_CICP_CP_SMPTE_240 = 7, /**< SMPTE 240 */
+ AOM_CICP_CP_GENERIC_FILM =
+ 8, /**< Generic film (color filters using illuminant C) */
+ AOM_CICP_CP_BT_2020 = 9, /**< BT.2020, BT.2100 */
+ AOM_CICP_CP_XYZ = 10, /**< SMPTE 428 (CIE 1921 XYZ) */
+ AOM_CICP_CP_SMPTE_431 = 11, /**< SMPTE RP 431-2 */
+ AOM_CICP_CP_SMPTE_432 = 12, /**< SMPTE EG 432-1 */
+ AOM_CICP_CP_RESERVED_13 = 13, /**< For future use (values 13 - 21) */
+ AOM_CICP_CP_EBU_3213 = 22, /**< EBU Tech. 3213-E */
+ AOM_CICP_CP_RESERVED_23 = 23 /**< For future use (values 23 - 255) */
+} aom_color_primaries_t; /**< alias for enum aom_color_primaries */
+
+/*!\brief List of supported transfer functions */
+typedef enum aom_transfer_characteristics {
+ AOM_CICP_TC_RESERVED_0 = 0, /**< For future use */
+ AOM_CICP_TC_BT_709 = 1, /**< BT.709 */
+ AOM_CICP_TC_UNSPECIFIED = 2, /**< Unspecified */
+ AOM_CICP_TC_RESERVED_3 = 3, /**< For future use */
+ AOM_CICP_TC_BT_470_M = 4, /**< BT.470 System M (historical) */
+ AOM_CICP_TC_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */
+ AOM_CICP_TC_BT_601 = 6, /**< BT.601 */
+ AOM_CICP_TC_SMPTE_240 = 7, /**< SMPTE 240 M */
+ AOM_CICP_TC_LINEAR = 8, /**< Linear */
+ AOM_CICP_TC_LOG_100 = 9, /**< Logarithmic (100 : 1 range) */
+ AOM_CICP_TC_LOG_100_SQRT10 =
+ 10, /**< Logarithmic (100 * Sqrt(10) : 1 range) */
+ AOM_CICP_TC_IEC_61966 = 11, /**< IEC 61966-2-4 */
+ AOM_CICP_TC_BT_1361 = 12, /**< BT.1361 */
+ AOM_CICP_TC_SRGB = 13, /**< sRGB or sYCC*/
+ AOM_CICP_TC_BT_2020_10_BIT = 14, /**< BT.2020 10-bit systems */
+ AOM_CICP_TC_BT_2020_12_BIT = 15, /**< BT.2020 12-bit systems */
+ AOM_CICP_TC_SMPTE_2084 = 16, /**< SMPTE ST 2084, ITU BT.2100 PQ */
+ AOM_CICP_TC_SMPTE_428 = 17, /**< SMPTE ST 428 */
+ AOM_CICP_TC_HLG = 18, /**< BT.2100 HLG, ARIB STD-B67 */
+ AOM_CICP_TC_RESERVED_19 = 19 /**< For future use (values 19-255) */
+} aom_transfer_characteristics_t; /**< alias for enum aom_transfer_function */
+
+/*!\brief List of supported matrix coefficients */
+typedef enum aom_matrix_coefficients {
+ AOM_CICP_MC_IDENTITY = 0, /**< Identity matrix */
+ AOM_CICP_MC_BT_709 = 1, /**< BT.709 */
+ AOM_CICP_MC_UNSPECIFIED = 2, /**< Unspecified */
+ AOM_CICP_MC_RESERVED_3 = 3, /**< For future use */
+ AOM_CICP_MC_FCC = 4, /**< US FCC 73.628 */
+ AOM_CICP_MC_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */
+ AOM_CICP_MC_BT_601 = 6, /**< BT.601 */
+ AOM_CICP_MC_SMPTE_240 = 7, /**< SMPTE 240 M */
+ AOM_CICP_MC_SMPTE_YCGCO = 8, /**< YCgCo */
+ AOM_CICP_MC_BT_2020_NCL =
+ 9, /**< BT.2020 non-constant luminance, BT.2100 YCbCr */
+ AOM_CICP_MC_BT_2020_CL = 10, /**< BT.2020 constant luminance */
+ AOM_CICP_MC_SMPTE_2085 = 11, /**< SMPTE ST 2085 YDzDx */
+ AOM_CICP_MC_CHROMAT_NCL =
+ 12, /**< Chromaticity-derived non-constant luminance */
+ AOM_CICP_MC_CHROMAT_CL = 13, /**< Chromaticity-derived constant luminance */
+ AOM_CICP_MC_ICTCP = 14, /**< BT.2100 ICtCp */
+ AOM_CICP_MC_RESERVED_15 = 15 /**< For future use (values 15-255) */
+} aom_matrix_coefficients_t;
+
+/*!\brief List of supported color range */
+typedef enum aom_color_range {
+ AOM_CR_STUDIO_RANGE = 0, /**<- Y [16..235], UV [16..240] (bit depth 8) */
+ /**<- Y [64..940], UV [64..960] (bit depth 10) */
+ /**<- Y [256..3760], UV [256..3840] (bit depth 12) */
+ AOM_CR_FULL_RANGE = 1 /**<- YUV/RGB [0..255] (bit depth 8) */
+ /**<- YUV/RGB [0..1023] (bit depth 10) */
+ /**<- YUV/RGB [0..4095] (bit depth 12) */
+} aom_color_range_t; /**< alias for enum aom_color_range */
+
+/*!\brief List of chroma sample positions */
+typedef enum aom_chroma_sample_position {
+ AOM_CSP_UNKNOWN = 0, /**< Unknown */
+ AOM_CSP_VERTICAL = 1, /**< Horizontally co-located with luma(0, 0)*/
+ /**< sample, between two vertical samples */
+ AOM_CSP_COLOCATED = 2, /**< Co-located with luma(0, 0) sample */
+ AOM_CSP_RESERVED = 3 /**< Reserved value */
+} aom_chroma_sample_position_t; /**< alias for enum aom_transfer_function */
+
+/*!\brief List of insert flags for Metadata
+ *
+ * These flags control how the library treats metadata during encode.
+ *
+ * While encoding, when metadata is added to an aom_image via
+ * aom_img_add_metadata(), the flag passed along with the metadata will
+ * determine where the metadata OBU will be placed in the encoded OBU stream.
+ * Metadata will be emitted into the output stream within the next temporal unit
+ * if it satisfies the specified insertion flag.
+ *
+ * During decoding, when the library encounters a metadata OBU, it is always
+ * flagged as AOM_MIF_ANY_FRAME and emitted with the next output aom_image.
+ */
+typedef enum aom_metadata_insert_flags {
+ AOM_MIF_NON_KEY_FRAME = 0, /**< Adds metadata if it's not keyframe */
+ AOM_MIF_KEY_FRAME = 1, /**< Adds metadata only if it's a keyframe */
+ AOM_MIF_ANY_FRAME = 2 /**< Adds metadata to any type of frame */
+} aom_metadata_insert_flags_t;
+
+/*!\brief Array of aom_metadata structs for an image. */
+typedef struct aom_metadata_array aom_metadata_array_t;
+
+/*!\brief Metadata payload. */
+typedef struct aom_metadata {
+ uint32_t type; /**< Metadata type */
+ uint8_t *payload; /**< Metadata payload data */
+ size_t sz; /**< Metadata payload size */
+ aom_metadata_insert_flags_t insert_flag; /**< Metadata insertion flag */
+} aom_metadata_t;
+
+/**\brief Image Descriptor */
+typedef struct aom_image {
+ aom_img_fmt_t fmt; /**< Image Format */
+ aom_color_primaries_t cp; /**< CICP Color Primaries */
+ aom_transfer_characteristics_t tc; /**< CICP Transfer Characteristics */
+ aom_matrix_coefficients_t mc; /**< CICP Matrix Coefficients */
+ int monochrome; /**< Whether image is monochrome */
+ aom_chroma_sample_position_t csp; /**< chroma sample position */
+ aom_color_range_t range; /**< Color Range */
+
+ /* Image storage dimensions */
+ unsigned int w; /**< Stored image width */
+ unsigned int h; /**< Stored image height */
+ unsigned int bit_depth; /**< Stored image bit-depth */
+
+ /* Image display dimensions */
+ unsigned int d_w; /**< Displayed image width */
+ unsigned int d_h; /**< Displayed image height */
+
+ /* Image intended rendering dimensions */
+ unsigned int r_w; /**< Intended rendering image width */
+ unsigned int r_h; /**< Intended rendering image height */
+
+ /* Chroma subsampling info */
+ unsigned int x_chroma_shift; /**< subsampling order, X */
+ unsigned int y_chroma_shift; /**< subsampling order, Y */
+
+/* Image data pointers. */
+#define AOM_PLANE_PACKED 0 /**< To be used for all packed formats */
+#define AOM_PLANE_Y 0 /**< Y (Luminance) plane */
+#define AOM_PLANE_U 1 /**< U (Chroma) plane */
+#define AOM_PLANE_V 2 /**< V (Chroma) plane */
+ /* planes[AOM_PLANE_V] = NULL and stride[AOM_PLANE_V] = 0 when fmt ==
+ * AOM_IMG_FMT_NV12 */
+ unsigned char *planes[3]; /**< pointer to the top left pixel for each plane */
+ int stride[3]; /**< stride between rows for each plane */
+ size_t sz; /**< data size */
+
+ int bps; /**< bits per sample (for packed formats) */
+
+ int temporal_id; /**< Temporal layer Id of image */
+ int spatial_id; /**< Spatial layer Id of image */
+
+ /*!\brief The following member may be set by the application to associate
+ * data with this image.
+ */
+ void *user_priv;
+
+ /* The following members should be treated as private. */
+ unsigned char *img_data; /**< private */
+ int img_data_owner; /**< private */
+ int self_allocd; /**< private */
+
+ aom_metadata_array_t
+ *metadata; /**< Metadata payloads associated with the image. */
+
+ void *fb_priv; /**< Frame buffer data associated with the image. */
+} aom_image_t; /**< alias for struct aom_image */
+
+/*!\brief Open a descriptor, allocating storage for the underlying image
+ *
+ * Returns a descriptor for storing an image of the given format. The
+ * storage for the image is allocated on the heap.
+ *
+ * \param[in] img Pointer to storage for descriptor. If this parameter
+ * is NULL, the storage for the descriptor will be
+ * allocated on the heap.
+ * \param[in] fmt Format for the image
+ * \param[in] d_w Width of the image
+ * \param[in] d_h Height of the image
+ * \param[in] align Alignment, in bytes, of the image buffer and
+ * each row in the image (stride).
+ *
+ * \return Returns a pointer to the initialized image descriptor. If the img
+ * parameter is non-null, the value of the img parameter will be
+ * returned.
+ */
+aom_image_t *aom_img_alloc(aom_image_t *img, aom_img_fmt_t fmt,
+ unsigned int d_w, unsigned int d_h,
+ unsigned int align);
+
+/*!\brief Open a descriptor, using existing storage for the underlying image
+ *
+ * Returns a descriptor for storing an image of the given format. The
+ * storage for the image has been allocated elsewhere, and a descriptor is
+ * desired to "wrap" that storage.
+ *
+ * \param[in] img Pointer to storage for descriptor. If this parameter
+ * is NULL, the storage for the descriptor will be
+ * allocated on the heap.
+ * \param[in] fmt Format for the image
+ * \param[in] d_w Width of the image
+ * \param[in] d_h Height of the image
+ * \param[in] align Alignment, in bytes, of each row in the image
+ * (stride).
+ * \param[in] img_data Storage to use for the image
+ *
+ * \return Returns a pointer to the initialized image descriptor. If the img
+ * parameter is non-null, the value of the img parameter will be
+ * returned.
+ */
+aom_image_t *aom_img_wrap(aom_image_t *img, aom_img_fmt_t fmt, unsigned int d_w,
+ unsigned int d_h, unsigned int align,
+ unsigned char *img_data);
+
+/*!\brief Open a descriptor, allocating storage for the underlying image with a
+ * border
+ *
+ * Returns a descriptor for storing an image of the given format and its
+ * borders. The storage for the image is allocated on the heap.
+ *
+ * \param[in] img Pointer to storage for descriptor. If this parameter
+ * is NULL, the storage for the descriptor will be
+ * allocated on the heap.
+ * \param[in] fmt Format for the image
+ * \param[in] d_w Width of the image
+ * \param[in] d_h Height of the image
+ * \param[in] align Alignment, in bytes, of the image buffer and
+ * each row in the image (stride).
+ * \param[in] size_align Alignment, in pixels, of the image width and height.
+ * \param[in] border A border that is padded on four sides of the image.
+ *
+ * \return Returns a pointer to the initialized image descriptor. If the img
+ * parameter is non-null, the value of the img parameter will be
+ * returned.
+ */
+aom_image_t *aom_img_alloc_with_border(aom_image_t *img, aom_img_fmt_t fmt,
+ unsigned int d_w, unsigned int d_h,
+ unsigned int align,
+ unsigned int size_align,
+ unsigned int border);
+
+/*!\brief Set the rectangle identifying the displayed portion of the image
+ *
+ * Updates the displayed rectangle (aka viewport) on the image surface to
+ * match the specified coordinates and size. Specifically, sets img->d_w,
+ * img->d_h, and elements of the img->planes[] array.
+ *
+ * \param[in] img Image descriptor
+ * \param[in] x leftmost column
+ * \param[in] y topmost row
+ * \param[in] w width
+ * \param[in] h height
+ * \param[in] border A border that is padded on four sides of the image.
+ *
+ * \return 0 if the requested rectangle is valid, nonzero (-1) otherwise.
+ */
+int aom_img_set_rect(aom_image_t *img, unsigned int x, unsigned int y,
+ unsigned int w, unsigned int h, unsigned int border);
+
+/*!\brief Flip the image vertically (top for bottom)
+ *
+ * Adjusts the image descriptor's pointers and strides to make the image
+ * be referenced upside-down.
+ *
+ * \param[in] img Image descriptor
+ */
+void aom_img_flip(aom_image_t *img);
+
+/*!\brief Close an image descriptor
+ *
+ * Frees all allocated storage associated with an image descriptor.
+ *
+ * \param[in] img Image descriptor
+ */
+void aom_img_free(aom_image_t *img);
+
+/*!\brief Get the width of a plane
+ *
+ * Get the width of a plane of an image
+ *
+ * \param[in] img Image descriptor
+ * \param[in] plane Plane index
+ */
+int aom_img_plane_width(const aom_image_t *img, int plane);
+
+/*!\brief Get the height of a plane
+ *
+ * Get the height of a plane of an image
+ *
+ * \param[in] img Image descriptor
+ * \param[in] plane Plane index
+ */
+int aom_img_plane_height(const aom_image_t *img, int plane);
+
+/*!\brief Add metadata to image.
+ *
+ * Adds metadata to aom_image_t.
+ * Function makes a copy of the provided data parameter.
+ * Metadata insertion point is controlled by insert_flag.
+ *
+ * \param[in] img Image descriptor
+ * \param[in] type Metadata type
+ * \param[in] data Metadata contents
+ * \param[in] sz Metadata contents size
+ * \param[in] insert_flag Metadata insert flag
+ *
+ * \return Returns 0 on success. If img or data is NULL, sz is 0, or memory
+ * allocation fails, it returns -1.
+ */
+int aom_img_add_metadata(aom_image_t *img, uint32_t type, const uint8_t *data,
+ size_t sz, aom_metadata_insert_flags_t insert_flag);
+
+/*!\brief Return a metadata payload stored within the image metadata array.
+ *
+ * Gets the metadata (aom_metadata_t) at the indicated index in the image
+ * metadata array.
+ *
+ * \param[in] img Pointer to image descriptor to get metadata from
+ * \param[in] index Metadata index to get from metadata array
+ *
+ * \return Returns a const pointer to the selected metadata, if img and/or index
+ * is invalid, it returns NULL.
+ */
+const aom_metadata_t *aom_img_get_metadata(const aom_image_t *img,
+ size_t index);
+
+/*!\brief Return the number of metadata blocks within the image.
+ *
+ * Gets the number of metadata blocks contained within the provided image
+ * metadata array.
+ *
+ * \param[in] img Pointer to image descriptor to get metadata number
+ * from.
+ *
+ * \return Returns the size of the metadata array. If img or metadata is NULL,
+ * it returns 0.
+ */
+size_t aom_img_num_metadata(const aom_image_t *img);
+
+/*!\brief Remove metadata from image.
+ *
+ * Removes all metadata in image metadata list and sets metadata list pointer
+ * to NULL.
+ *
+ * \param[in] img Image descriptor
+ */
+void aom_img_remove_metadata(aom_image_t *img);
+
+/*!\brief Allocate memory for aom_metadata struct.
+ *
+ * Allocates storage for the metadata payload, sets its type and copies the
+ * payload data into the aom_metadata struct. A metadata payload buffer of size
+ * sz is allocated and sz bytes are copied from data into the payload buffer.
+ *
+ * \param[in] type Metadata type
+ * \param[in] data Metadata data pointer
+ * \param[in] sz Metadata size
+ * \param[in] insert_flag Metadata insert flag
+ *
+ * \return Returns the newly allocated aom_metadata struct. If data is NULL,
+ * sz is 0, or memory allocation fails, it returns NULL.
+ */
+aom_metadata_t *aom_img_metadata_alloc(uint32_t type, const uint8_t *data,
+ size_t sz,
+ aom_metadata_insert_flags_t insert_flag);
+
+/*!\brief Free metadata struct.
+ *
+ * Free metadata struct and its buffer.
+ *
+ * \param[in] metadata Metadata struct pointer
+ */
+void aom_img_metadata_free(aom_metadata_t *metadata);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // AOM_AOM_AOM_IMAGE_H_
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_integer.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_integer.h
new file mode 100644
index 0000000..d9bba09
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aom_integer.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+#ifndef AOM_AOM_AOM_INTEGER_H_
+#define AOM_AOM_AOM_INTEGER_H_
+
+/* get ptrdiff_t, size_t, wchar_t, NULL */
+#include
+
+#if defined(_MSC_VER)
+#define AOM_FORCE_INLINE __forceinline
+#define AOM_INLINE __inline
+#else
+#define AOM_FORCE_INLINE __inline__ __attribute__((always_inline))
+#define AOM_INLINE inline
+#endif
+
+/* Assume platforms have the C99 standard integer types. */
+
+#if defined(__cplusplus)
+#if !defined(__STDC_FORMAT_MACROS)
+#define __STDC_FORMAT_MACROS
+#endif
+#if !defined(__STDC_LIMIT_MACROS)
+#define __STDC_LIMIT_MACROS
+#endif
+#endif // __cplusplus
+
+#include
+#include
+
+#if defined(__cplusplus)
+extern "C" {
+#endif // __cplusplus
+
+// Returns size of uint64_t when encoded using LEB128.
+size_t aom_uleb_size_in_bytes(uint64_t value);
+
+// Returns 0 on success, -1 on decode failure.
+// On success, 'value' stores the decoded LEB128 value and 'length' stores
+// the number of bytes decoded.
+int aom_uleb_decode(const uint8_t *buffer, size_t available, uint64_t *value,
+ size_t *length);
+
+// Encodes LEB128 integer. Returns 0 when successful, and -1 upon failure.
+int aom_uleb_encode(uint64_t value, size_t available, uint8_t *coded_value,
+ size_t *coded_size);
+
+// Encodes LEB128 integer to size specified. Returns 0 when successful, and -1
+// upon failure.
+// Note: This will write exactly pad_to_size bytes; if the value cannot be
+// encoded in this many bytes, then this will fail.
+int aom_uleb_encode_fixed_size(uint64_t value, size_t available,
+ size_t pad_to_size, uint8_t *coded_value,
+ size_t *coded_size);
+
+#if defined(__cplusplus)
+} // extern "C"
+#endif // __cplusplus
+
+#endif // AOM_AOM_AOM_INTEGER_H_
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aomcx.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aomcx.h
new file mode 100644
index 0000000..8f12936
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/aom/aomcx.h
@@ -0,0 +1,2080 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+#ifndef AOM_AOM_AOMCX_H_
+#define AOM_AOM_AOMCX_H_
+
+/*!\defgroup aom_encoder AOMedia AOM/AV1 Encoder
+ * \ingroup aom
+ *
+ * @{
+ */
+#include "aom/aom.h"
+#include "aom/aom_encoder.h"
+#include "aom/aom_external_partition.h"
+
+/*!\file
+ * \brief Provides definitions for using AOM or AV1 encoder algorithm within the
+ * aom Codec Interface.
+ *
+ * Several interfaces are excluded with CONFIG_REALTIME_ONLY build:
+ * Global motion
+ * Warped motion
+ * OBMC
+ * TPL model
+ * Loop restoration
+ *
+ * The following features are also disabled with CONFIG_REALTIME_ONLY:
+ * AV1E_SET_QUANT_B_ADAPT
+ * CNN
+ * 4X rectangular blocks
+ * 4X rectangular transform in intra prediction
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!\name Algorithm interface for AV1
+ *
+ * This interface provides the capability to encode raw AV1 streams.
+ *@{
+ */
+
+/*!\brief A single instance of the AV1 encoder.
+ *\deprecated This access mechanism is provided for backwards compatibility;
+ * prefer aom_codec_av1_cx().
+ */
+extern aom_codec_iface_t aom_codec_av1_cx_algo;
+
+/*!\brief The interface to the AV1 encoder.
+ */
+extern aom_codec_iface_t *aom_codec_av1_cx(void);
+/*!@} - end algorithm interface member group */
+
+/*
+ * Algorithm Flags
+ */
+
+/*!\brief Don't reference the last frame
+ *
+ * When this flag is set, the encoder will not use the last frame as a
+ * predictor. When not set, the encoder will choose whether to use the
+ * last frame or not automatically.
+ */
+#define AOM_EFLAG_NO_REF_LAST (1 << 16)
+/*!\brief Don't reference the last2 frame
+ *
+ * When this flag is set, the encoder will not use the last2 frame as a
+ * predictor. When not set, the encoder will choose whether to use the
+ * last2 frame or not automatically.
+ */
+#define AOM_EFLAG_NO_REF_LAST2 (1 << 17)
+/*!\brief Don't reference the last3 frame
+ *
+ * When this flag is set, the encoder will not use the last3 frame as a
+ * predictor. When not set, the encoder will choose whether to use the
+ * last3 frame or not automatically.
+ */
+#define AOM_EFLAG_NO_REF_LAST3 (1 << 18)
+/*!\brief Don't reference the golden frame
+ *
+ * When this flag is set, the encoder will not use the golden frame as a
+ * predictor. When not set, the encoder will choose whether to use the
+ * golden frame or not automatically.
+ */
+#define AOM_EFLAG_NO_REF_GF (1 << 19)
+
+/*!\brief Don't reference the alternate reference frame
+ *
+ * When this flag is set, the encoder will not use the alt ref frame as a
+ * predictor. When not set, the encoder will choose whether to use the
+ * alt ref frame or not automatically.
+ */
+#define AOM_EFLAG_NO_REF_ARF (1 << 20)
+/*!\brief Don't reference the bwd reference frame
+ *
+ * When this flag is set, the encoder will not use the bwd ref frame as a
+ * predictor. When not set, the encoder will choose whether to use the
+ * bwd ref frame or not automatically.
+ */
+#define AOM_EFLAG_NO_REF_BWD (1 << 21)
+/*!\brief Don't reference the alt2 reference frame
+ *
+ * When this flag is set, the encoder will not use the alt2 ref frame as a
+ * predictor. When not set, the encoder will choose whether to use the
+ * alt2 ref frame or not automatically.
+ */
+#define AOM_EFLAG_NO_REF_ARF2 (1 << 22)
+
+/*!\brief Don't update the last frame
+ *
+ * When this flag is set, the encoder will not update the last frame with
+ * the contents of the current frame.
+ */
+#define AOM_EFLAG_NO_UPD_LAST (1 << 23)
+
+/*!\brief Don't update the golden frame
+ *
+ * When this flag is set, the encoder will not update the golden frame with
+ * the contents of the current frame.
+ */
+#define AOM_EFLAG_NO_UPD_GF (1 << 24)
+
+/*!\brief Don't update the alternate reference frame
+ *
+ * When this flag is set, the encoder will not update the alt ref frame with
+ * the contents of the current frame.
+ */
+#define AOM_EFLAG_NO_UPD_ARF (1 << 25)
+/*!\brief Disable entropy update
+ *
+ * When this flag is set, the encoder will not update its internal entropy
+ * model based on the entropy of this frame.
+ */
+#define AOM_EFLAG_NO_UPD_ENTROPY (1 << 26)
+/*!\brief Disable ref frame mvs
+ *
+ * When this flag is set, the encoder will not allow frames to
+ * be encoded using mfmv.
+ */
+#define AOM_EFLAG_NO_REF_FRAME_MVS (1 << 27)
+/*!\brief Enable error resilient frame
+ *
+ * When this flag is set, the encoder will code frames as error
+ * resilient.
+ */
+#define AOM_EFLAG_ERROR_RESILIENT (1 << 28)
+/*!\brief Enable s frame mode
+ *
+ * When this flag is set, the encoder will code frames as an
+ * s frame.
+ */
+#define AOM_EFLAG_SET_S_FRAME (1 << 29)
+/*!\brief Force primary_ref_frame to PRIMARY_REF_NONE
+ *
+ * When this flag is set, the encoder will set a frame's primary_ref_frame
+ * to PRIMARY_REF_NONE
+ */
+#define AOM_EFLAG_SET_PRIMARY_REF_NONE (1 << 30)
+
+/*!\brief AVx encoder control functions
+ *
+ * This set of macros define the control functions available for AVx
+ * encoder interface.
+ * The range of encode control ID is 7-229(max).
+ *
+ * \sa #aom_codec_control(aom_codec_ctx_t *ctx, int ctrl_id, ...)
+ */
+enum aome_enc_control_id {
+ /*!\brief Codec control function to set which reference frame encoder can use,
+ * int parameter.
+ */
+ AOME_USE_REFERENCE = 7,
+
+ /*!\brief Codec control function to pass an ROI map to encoder, aom_roi_map_t*
+ * parameter.
+ */
+ AOME_SET_ROI_MAP = 8,
+
+ /*!\brief Codec control function to pass an Active map to encoder,
+ * aom_active_map_t* parameter.
+ */
+ AOME_SET_ACTIVEMAP = 9,
+
+ /* NOTE: enum 10 unused */
+
+ /*!\brief Codec control function to set encoder scaling mode,
+ * aom_scaling_mode_t* parameter.
+ */
+ AOME_SET_SCALEMODE = 11,
+
+ /*!\brief Codec control function to set encoder spatial layer id, unsigned int
+ * parameter.
+ */
+ AOME_SET_SPATIAL_LAYER_ID = 12,
+
+ /*!\brief Codec control function to set encoder internal speed settings,
+ * int parameter
+ *
+ * Changes in this value influences the complexity of algorithms used in
+ * encoding process, values greater than 0 will increase encoder speed at
+ * the expense of quality.
+ *
+ * Valid range: 0..10. 0 runs the slowest, and 10 runs the fastest;
+ * quality improves as speed decreases (since more compression
+ * possibilities are explored).
+ *
+ * NOTE: 10 is only allowed in AOM_USAGE_REALTIME. In AOM_USAGE_GOOD_QUALITY
+ * and AOM_USAGE_ALL_INTRA, 9 is the highest allowed value. However,
+ * AOM_USAGE_GOOD_QUALITY treats 7..9 the same as 6. Also, AOM_USAGE_REALTIME
+ * treats 0..4 the same as 5.
+ */
+ AOME_SET_CPUUSED = 13,
+
+ /*!\brief Codec control function to enable automatic set and use alf frames,
+ * unsigned int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AOME_SET_ENABLEAUTOALTREF = 14,
+
+ /* NOTE: enum 15 unused */
+
+ /*!\brief Codec control function to set the sharpness parameter,
+ * unsigned int parameter.
+ *
+ * This parameter controls the level at which rate-distortion optimization of
+ * transform coefficients favours sharpness in the block.
+ *
+ * Valid range: 0..7. The default is 0. Values 1-7 will avoid eob and skip
+ * block optimization and will change rdmult in favour of block sharpness.
+ */
+ AOME_SET_SHARPNESS = AOME_SET_ENABLEAUTOALTREF + 2, // 16
+
+ /*!\brief Codec control function to set the threshold for MBs treated static,
+ * unsigned int parameter
+ */
+ AOME_SET_STATIC_THRESHOLD = 17,
+
+ /* NOTE: enum 18 unused */
+
+ /*!\brief Codec control function to get last quantizer chosen by the encoder,
+ * int* parameter
+ *
+ * Return value uses internal quantizer scale defined by the codec.
+ */
+ AOME_GET_LAST_QUANTIZER = AOME_SET_STATIC_THRESHOLD + 2, // 19
+
+ /*!\brief Codec control function to get last quantizer chosen by the encoder,
+ * int* parameter
+ *
+ * Return value uses the 0..63 scale as used by the rc_*_quantizer config
+ * parameters.
+ */
+ AOME_GET_LAST_QUANTIZER_64 = 20,
+
+ /*!\brief Codec control function to set the max no of frames to create arf,
+ * unsigned int parameter
+ */
+ AOME_SET_ARNR_MAXFRAMES = 21,
+
+ /*!\brief Codec control function to set the filter strength for the arf,
+ * unsigned int parameter
+ */
+ AOME_SET_ARNR_STRENGTH = 22,
+
+ /* NOTE: enum 23 unused */
+
+ /*!\brief Codec control function to set visual tuning, aom_tune_metric (int)
+ * parameter
+ *
+ * The default is AOM_TUNE_PSNR.
+ */
+ AOME_SET_TUNING = AOME_SET_ARNR_STRENGTH + 2, // 24
+
+ /*!\brief Codec control function to set constrained / constant quality level,
+ * unsigned int parameter
+ *
+ * Valid range: 0..63
+ *
+ * \attention For this value to be used aom_codec_enc_cfg_t::rc_end_usage
+ * must be set to #AOM_CQ or #AOM_Q.
+ */
+ AOME_SET_CQ_LEVEL = 25,
+
+ /*!\brief Codec control function to set max data rate for intra frames,
+ * unsigned int parameter
+ *
+ * This value controls additional clamping on the maximum size of a
+ * keyframe. It is expressed as a percentage of the average
+ * per-frame bitrate, with the special (and default) value 0 meaning
+ * unlimited, or no additional clamping beyond the codec's built-in
+ * algorithm.
+ *
+ * For example, to allocate no more than 4.5 frames worth of bitrate
+ * to a keyframe, set this to 450.
+ */
+ AOME_SET_MAX_INTRA_BITRATE_PCT = 26,
+
+ /*!\brief Codec control function to set number of spatial layers, int
+ * parameter
+ */
+ AOME_SET_NUMBER_SPATIAL_LAYERS = 27,
+
+ /*!\brief Codec control function to set max data rate for inter frames,
+ * unsigned int parameter
+ *
+ * This value controls additional clamping on the maximum size of an
+ * inter frame. It is expressed as a percentage of the average
+ * per-frame bitrate, with the special (and default) value 0 meaning
+ * unlimited, or no additional clamping beyond the codec's built-in
+ * algorithm.
+ *
+ * For example, to allow no more than 4.5 frames worth of bitrate
+ * to an inter frame, set this to 450.
+ */
+ AV1E_SET_MAX_INTER_BITRATE_PCT = AOME_SET_MAX_INTRA_BITRATE_PCT + 2, // 28
+
+ /*!\brief Boost percentage for Golden Frame in CBR mode, unsigned int
+ * parameter
+ *
+ * This value controls the amount of boost given to Golden Frame in
+ * CBR mode. It is expressed as a percentage of the average
+ * per-frame bitrate, with the special (and default) value 0 meaning
+ * the feature is off, i.e., no golden frame boost in CBR mode and
+ * average bitrate target is used.
+ *
+ * For example, to allow 100% more bits, i.e, 2X, in a golden frame
+ * than average frame, set this to 100.
+ */
+ AV1E_SET_GF_CBR_BOOST_PCT = 29,
+
+ /* NOTE: enum 30 unused */
+
+ /*!\brief Codec control function to set lossless encoding mode, unsigned int
+ * parameter
+ *
+ * AV1 can operate in lossless encoding mode, in which the bitstream
+ * produced will be able to decode and reconstruct a perfect copy of
+ * input source.
+ *
+ * - 0 = normal coding mode, may be lossy (default)
+ * - 1 = lossless coding mode
+ */
+ AV1E_SET_LOSSLESS = AV1E_SET_GF_CBR_BOOST_PCT + 2, // 31
+
+ /*!\brief Codec control function to enable the row based multi-threading
+ * of the encoder, unsigned int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ROW_MT = 32,
+
+ /*!\brief Codec control function to set number of tile columns. unsigned int
+ * parameter
+ *
+ * In encoding and decoding, AV1 allows an input image frame be partitioned
+ * into separate vertical tile columns, which can be encoded or decoded
+ * independently. This enables easy implementation of parallel encoding and
+ * decoding. The parameter for this control describes the number of tile
+ * columns (in log2 units), which has a valid range of [0, 6]:
+ * \verbatim
+ 0 = 1 tile column
+ 1 = 2 tile columns
+ 2 = 4 tile columns
+ .....
+ n = 2**n tile columns
+ \endverbatim
+ * By default, the value is 0, i.e. one single column tile for entire image.
+ */
+ AV1E_SET_TILE_COLUMNS = 33,
+
+ /*!\brief Codec control function to set number of tile rows, unsigned int
+ * parameter
+ *
+ * In encoding and decoding, AV1 allows an input image frame be partitioned
+ * into separate horizontal tile rows, which can be encoded or decoded
+ * independently. The parameter for this control describes the number of tile
+ * rows (in log2 units), which has a valid range of [0, 6]:
+ * \verbatim
+ 0 = 1 tile row
+ 1 = 2 tile rows
+ 2 = 4 tile rows
+ .....
+ n = 2**n tile rows
+ \endverbatim
+ * By default, the value is 0, i.e. one single row tile for entire image.
+ */
+ AV1E_SET_TILE_ROWS = 34,
+
+ /*!\brief Codec control function to enable RDO modulated by frame temporal
+ * dependency, unsigned int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ *
+ * \note Excluded from CONFIG_REALTIME_ONLY build.
+ */
+ AV1E_SET_ENABLE_TPL_MODEL = 35,
+
+ /*!\brief Codec control function to enable temporal filtering on key frame,
+ * unsigned int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable without overlay (default)
+ * - 2 = enable with overlay
+ */
+ AV1E_SET_ENABLE_KEYFRAME_FILTERING = 36,
+
+ /*!\brief Codec control function to enable frame parallel decoding feature,
+ * unsigned int parameter
+ *
+ * AV1 has a bitstream feature to reduce decoding dependency between frames
+ * by turning off backward update of probability context used in encoding
+ * and decoding. This allows staged parallel processing of more than one
+ * video frames in the decoder. This control function provides a means to
+ * turn this feature on or off for bitstreams produced by encoder.
+ *
+ * - 0 = disable (default)
+ * - 1 = enable
+ */
+ AV1E_SET_FRAME_PARALLEL_DECODING = 37,
+
+ /*!\brief Codec control function to enable error_resilient_mode, int parameter
+ *
+ * AV1 has a bitstream feature to guarantee parseability of a frame
+ * by turning on the error_resilient_decoding mode, even though the
+ * reference buffers are unreliable or not received.
+ *
+ * - 0 = disable (default)
+ * - 1 = enable
+ */
+ AV1E_SET_ERROR_RESILIENT_MODE = 38,
+
+ /*!\brief Codec control function to enable s_frame_mode, int parameter
+ *
+ * AV1 has a bitstream feature to designate certain frames as S-frames,
+ * from where we can switch to a different stream,
+ * even though the reference buffers may not be exactly identical.
+ *
+ * - 0 = disable (default)
+ * - 1 = enable
+ */
+ AV1E_SET_S_FRAME_MODE = 39,
+
+ /*!\brief Codec control function to set adaptive quantization mode, unsigned
+ * int parameter
+ *
+ * AV1 has a segment based feature that allows encoder to adaptively change
+ * quantization parameter for each segment within a frame to improve the
+ * subjective quality. This control makes encoder operate in one of the
+ * several AQ modes supported.
+ *
+ * - 0 = disable (default)
+ * - 1 = variance
+ * - 2 = complexity
+ * - 3 = cyclic refresh
+ */
+ AV1E_SET_AQ_MODE = 40,
+
+ /*!\brief Codec control function to enable/disable periodic Q boost, unsigned
+ * int parameter
+ *
+ * One AV1 encoder speed feature is to enable quality boost by lowering
+ * frame level Q periodically. This control function provides a means to
+ * turn on/off this feature.
+ *
+ * - 0 = disable (default)
+ * - 1 = enable
+ */
+ AV1E_SET_FRAME_PERIODIC_BOOST = 41,
+
+ /*!\brief Codec control function to set noise sensitivity, unsigned int
+ * parameter
+ *
+ * - 0 = disable (default)
+ * - 1 = enable (Y only)
+ */
+ AV1E_SET_NOISE_SENSITIVITY = 42,
+
+ /*!\brief Codec control function to set content type, aom_tune_content
+ * parameter
+ *
+ * - AOM_CONTENT_DEFAULT = Regular video content (default)
+ * - AOM_CONTENT_SCREEN = Screen capture content
+ * - AOM_CONTENT_FILM = Film content
+ */
+ AV1E_SET_TUNE_CONTENT = 43,
+
+ /*!\brief Codec control function to set CDF update mode, unsigned int
+ * parameter
+ *
+ * - 0: no update
+ * - 1: update on every frame (default)
+ * - 2: selectively update
+ */
+ AV1E_SET_CDF_UPDATE_MODE = 44,
+
+ /*!\brief Codec control function to set color space info, int parameter
+ *
+ * - 0 = For future use
+ * - 1 = BT.709
+ * - 2 = Unspecified (default)
+ * - 3 = For future use
+ * - 4 = BT.470 System M (historical)
+ * - 5 = BT.470 System B, G (historical)
+ * - 6 = BT.601
+ * - 7 = SMPTE 240
+ * - 8 = Generic film (color filters using illuminant C)
+ * - 9 = BT.2020, BT.2100
+ * - 10 = SMPTE 428 (CIE 1921 XYZ)
+ * - 11 = SMPTE RP 431-2
+ * - 12 = SMPTE EG 432-1
+ * - 13..21 = For future use
+ * - 22 = EBU Tech. 3213-E
+ * - 23 = For future use
+ */
+ AV1E_SET_COLOR_PRIMARIES = 45,
+
+ /*!\brief Codec control function to set transfer function info, int parameter
+ *
+ * - 0 = For future use
+ * - 1 = BT.709
+ * - 2 = Unspecified (default)
+ * - 3 = For future use
+ * - 4 = BT.470 System M (historical)
+ * - 5 = BT.470 System B, G (historical)
+ * - 6 = BT.601
+ * - 7 = SMPTE 240 M
+ * - 8 = Linear
+ * - 9 = Logarithmic (100 : 1 range)
+ * - 10 = Logarithmic (100 * Sqrt(10) : 1 range)
+ * - 11 = IEC 61966-2-4
+ * - 12 = BT.1361
+ * - 13 = sRGB or sYCC
+ * - 14 = BT.2020 10-bit systems
+ * - 15 = BT.2020 12-bit systems
+ * - 16 = SMPTE ST 2084, ITU BT.2100 PQ
+ * - 17 = SMPTE ST 428
+ * - 18 = BT.2100 HLG, ARIB STD-B67
+ * - 19 = For future use
+ */
+ AV1E_SET_TRANSFER_CHARACTERISTICS = 46,
+
+ /*!\brief Codec control function to set transfer function info, int parameter
+ *
+ * - 0 = Identity matrix
+ * - 1 = BT.709
+ * - 2 = Unspecified (default)
+ * - 3 = For future use
+ * - 4 = US FCC 73.628
+ * - 5 = BT.470 System B, G (historical)
+ * - 6 = BT.601
+ * - 7 = SMPTE 240 M
+ * - 8 = YCgCo
+ * - 9 = BT.2020 non-constant luminance, BT.2100 YCbCr
+ * - 10 = BT.2020 constant luminance
+ * - 11 = SMPTE ST 2085 YDzDx
+ * - 12 = Chromaticity-derived non-constant luminance
+ * - 13 = Chromaticity-derived constant luminance
+ * - 14 = BT.2100 ICtCp
+ * - 15 = For future use
+ */
+ AV1E_SET_MATRIX_COEFFICIENTS = 47,
+
+ /*!\brief Codec control function to set chroma 4:2:0 sample position info,
+ * aom_chroma_sample_position_t parameter
+ *
+ * AOM_CSP_UNKNOWN is default
+ */
+ AV1E_SET_CHROMA_SAMPLE_POSITION = 48,
+
+ /*!\brief Codec control function to set minimum interval between GF/ARF
+ * frames, unsigned int parameter
+ *
+ * By default the value is set as 4.
+ */
+ AV1E_SET_MIN_GF_INTERVAL = 49,
+
+ /*!\brief Codec control function to set minimum interval between GF/ARF
+ * frames, unsigned int parameter
+ *
+ * By default the value is set as 16.
+ */
+ AV1E_SET_MAX_GF_INTERVAL = 50,
+
+ /*!\brief Codec control function to get an active map back from the encoder,
+ aom_active_map_t* parameter
+ */
+ AV1E_GET_ACTIVEMAP = 51,
+
+ /*!\brief Codec control function to set color range bit, int parameter
+ *
+ * - 0 = Limited range, 16..235 or HBD equivalent (default)
+ * - 1 = Full range, 0..255 or HBD equivalent
+ */
+ AV1E_SET_COLOR_RANGE = 52,
+
+ /*!\brief Codec control function to set intended rendering image size,
+ * int32_t[2] parameter
+ *
+ * By default, this is identical to the image size in pixels.
+ */
+ AV1E_SET_RENDER_SIZE = 53,
+
+ /*!\brief Control to set target sequence level index for a certain operating
+ * point (OP), int parameter
+ * Possible values are in the form of "ABxy".
+ * - AB: OP index.
+ * - xy: Target level index for the OP. Can be values 0~23 (corresponding to
+ * level 2.0 ~ 7.3, note levels 2.2, 2.3, 3.2, 3.3, 4.2, 4.3, 7.0, 7.1, 7.2
+ * & 7.3 are undefined) or 24 (keep level stats only for level monitoring)
+ * or 31 (maximum level parameter, no level-based constraints).
+ *
+ * E.g.:
+ * - "0" means target level index 0 (2.0) for the 0th OP;
+ * - "109" means target level index 9 (4.1) for the 1st OP;
+ * - "1019" means target level index 19 (6.3) for the 10th OP.
+ *
+ * If the target level is not specified for an OP, the maximum level parameter
+ * of 31 is used as default.
+ */
+ AV1E_SET_TARGET_SEQ_LEVEL_IDX = 54,
+
+ /*!\brief Codec control function to get sequence level index for each
+ * operating point. int* parameter. There can be at most 32 operating points.
+ * The results will be written into a provided integer array of sufficient
+ * size.
+ */
+ AV1E_GET_SEQ_LEVEL_IDX = 55,
+
+ /*!\brief Codec control function to set intended superblock size, unsigned int
+ * parameter
+ *
+ * By default, the superblock size is determined separately for each
+ * frame by the encoder.
+ */
+ AV1E_SET_SUPERBLOCK_SIZE = 56,
+
+ /*!\brief Codec control function to enable automatic set and use of
+ * bwd-pred frames, unsigned int parameter
+ *
+ * - 0 = disable (default)
+ * - 1 = enable
+ */
+ AOME_SET_ENABLEAUTOBWDREF = 57,
+
+ /*!\brief Codec control function to encode with CDEF, unsigned int parameter
+ *
+ * CDEF is the constrained directional enhancement filter which is an
+ * in-loop filter aiming to remove coding artifacts
+ *
+ * - 0 = disable
+ * - 1 = enable for all frames (default)
+ * - 2 = disable for non-reference frames
+ */
+ AV1E_SET_ENABLE_CDEF = 58,
+
+ /*!\brief Codec control function to encode with Loop Restoration Filter,
+ * unsigned int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ *
+ * \note Excluded from CONFIG_REALTIME_ONLY build.
+ */
+ AV1E_SET_ENABLE_RESTORATION = 59,
+
+ /*!\brief Codec control function to force video mode, unsigned int parameter
+ *
+ * - 0 = do not force video mode (default)
+ * - 1 = force video mode even for a single frame
+ */
+ AV1E_SET_FORCE_VIDEO_MODE = 60,
+
+ /*!\brief Codec control function to predict with OBMC mode, unsigned int
+ * parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ *
+ * \note Excluded from CONFIG_REALTIME_ONLY build.
+ */
+ AV1E_SET_ENABLE_OBMC = 61,
+
+ /*!\brief Codec control function to encode without trellis quantization,
+ * unsigned int parameter
+ *
+ * - 0 = apply trellis quantization (default)
+ * - 1 = do not apply trellis quantization
+ * - 2 = disable trellis quantization in rd search
+ * - 3 = disable trellis quantization in estimate yrd
+ */
+ AV1E_SET_DISABLE_TRELLIS_QUANT = 62,
+
+ /*!\brief Codec control function to encode with quantisation matrices,
+ * unsigned int parameter
+ *
+ * AOM can operate with default quantisation matrices dependent on
+ * quantisation level and block type.
+ *
+ * - 0 = disable (default)
+ * - 1 = enable
+ */
+ AV1E_SET_ENABLE_QM = 63,
+
+ /*!\brief Codec control function to set the min quant matrix flatness,
+ * unsigned int parameter
+ *
+ * AOM can operate with different ranges of quantisation matrices.
+ * As quantisation levels increase, the matrices get flatter. This
+ * control sets the minimum level of flatness from which the matrices
+ * are determined.
+ *
+ * By default, the encoder sets this minimum at half the available
+ * range.
+ */
+ AV1E_SET_QM_MIN = 64,
+
+ /*!\brief Codec control function to set the max quant matrix flatness,
+ * unsigned int parameter
+ *
+ * AOM can operate with different ranges of quantisation matrices.
+ * As quantisation levels increase, the matrices get flatter. This
+ * control sets the maximum level of flatness possible.
+ *
+ * By default, the encoder sets this maximum at the top of the
+ * available range.
+ */
+ AV1E_SET_QM_MAX = 65,
+
+ /*!\brief Codec control function to set the min quant matrix flatness,
+ * unsigned int parameter
+ *
+ * AOM can operate with different ranges of quantisation matrices.
+ * As quantisation levels increase, the matrices get flatter. This
+ * control sets the flatness for luma (Y).
+ *
+ * By default, the encoder sets this minimum at half the available
+ * range.
+ */
+ AV1E_SET_QM_Y = 66,
+
+ /*!\brief Codec control function to set the min quant matrix flatness,
+ * unsigned int parameter
+ *
+ * AOM can operate with different ranges of quantisation matrices.
+ * As quantisation levels increase, the matrices get flatter. This
+ * control sets the flatness for chroma (U).
+ *
+ * By default, the encoder sets this minimum at half the available
+ * range.
+ */
+ AV1E_SET_QM_U = 67,
+
+ /*!\brief Codec control function to set the min quant matrix flatness,
+ * unsigned int parameter
+ *
+ * AOM can operate with different ranges of quantisation matrices.
+ * As quantisation levels increase, the matrices get flatter. This
+ * control sets the flatness for chrome (V).
+ *
+ * By default, the encoder sets this minimum at half the available
+ * range.
+ */
+ AV1E_SET_QM_V = 68,
+
+ /* NOTE: enum 69 unused */
+
+ /*!\brief Codec control function to set a maximum number of tile groups,
+ * unsigned int parameter
+ *
+ * This will set the maximum number of tile groups. This will be
+ * overridden if an MTU size is set. The default value is 1.
+ */
+ AV1E_SET_NUM_TG = 70,
+
+ /*!\brief Codec control function to set an MTU size for a tile group, unsigned
+ * int parameter
+ *
+ * This will set the maximum number of bytes in a tile group. This can be
+ * exceeded only if a single tile is larger than this amount.
+ *
+ * By default, the value is 0, in which case a fixed number of tile groups
+ * is used.
+ */
+ AV1E_SET_MTU = 71,
+
+ /* NOTE: enum 72 unused */
+
+ /*!\brief Codec control function to enable/disable rectangular partitions, int
+ * parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_RECT_PARTITIONS = 73,
+
+ /*!\brief Codec control function to enable/disable AB partitions, int
+ * parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_AB_PARTITIONS = 74,
+
+ /*!\brief Codec control function to enable/disable 1:4 and 4:1 partitions, int
+ * parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_1TO4_PARTITIONS = 75,
+
+ /*!\brief Codec control function to set min partition size, int parameter
+ *
+ * min_partition_size is applied to both width and height of the partition.
+ * i.e, both width and height of a partition can not be smaller than
+ * the min_partition_size, except the partition at the picture boundary.
+ *
+ * Valid values: [4, 8, 16, 32, 64, 128]. The default value is 4 for
+ * 4x4.
+ */
+ AV1E_SET_MIN_PARTITION_SIZE = 76,
+
+ /*!\brief Codec control function to set max partition size, int parameter
+ *
+ * max_partition_size is applied to both width and height of the partition.
+ * i.e, both width and height of a partition can not be larger than
+ * the max_partition_size.
+ *
+ * Valid values:[4, 8, 16, 32, 64, 128] The default value is 128 for
+ * 128x128.
+ */
+ AV1E_SET_MAX_PARTITION_SIZE = 77,
+
+ /*!\brief Codec control function to turn on / off intra edge filter
+ * at sequence level, int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_INTRA_EDGE_FILTER = 78,
+
+ /*!\brief Codec control function to turn on / off frame order hint (int
+ * parameter). Affects: joint compound mode, motion field motion vector,
+ * ref frame sign bias
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_ORDER_HINT = 79,
+
+ /*!\brief Codec control function to turn on / off 64-length transforms, int
+ * parameter
+ *
+ * This will enable or disable usage of length 64 transforms in any
+ * direction.
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_TX64 = 80,
+
+ /*!\brief Codec control function to turn on / off flip and identity
+ * transforms, int parameter
+ *
+ * This will enable or disable usage of flip and identity transform
+ * types in any direction. If enabled, this includes:
+ * - FLIPADST_DCT
+ * - DCT_FLIPADST
+ * - FLIPADST_FLIPADST
+ * - ADST_FLIPADST
+ * - FLIPADST_ADST
+ * - IDTX
+ * - V_DCT
+ * - H_DCT
+ * - V_ADST
+ * - H_ADST
+ * - V_FLIPADST
+ * - H_FLIPADST
+ *
+ * Valid values:
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_FLIP_IDTX = 81,
+
+ /*!\brief Codec control function to turn on / off rectangular transforms, int
+ * parameter
+ *
+ * This will enable or disable usage of rectangular transforms. NOTE:
+ * Rectangular transforms only enabled when corresponding rectangular
+ * partitions are.
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_RECT_TX = 82,
+
+ /*!\brief Codec control function to turn on / off dist-wtd compound mode
+ * at sequence level, int parameter
+ *
+ * This will enable or disable distance-weighted compound mode.
+ * \attention If AV1E_SET_ENABLE_ORDER_HINT is 0, then this flag is forced
+ * to 0.
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_DIST_WTD_COMP = 83,
+
+ /*!\brief Codec control function to turn on / off ref frame mvs (mfmv) usage
+ * at sequence level, int parameter
+ *
+ * \attention If AV1E_SET_ENABLE_ORDER_HINT is 0, then this flag is forced
+ * to 0.
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_REF_FRAME_MVS = 84,
+
+ /*!\brief Codec control function to set temporal mv prediction
+ * enabling/disabling at frame level, int parameter
+ *
+ * \attention If AV1E_SET_ENABLE_REF_FRAME_MVS is 0, then this flag is
+ * forced to 0.
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ALLOW_REF_FRAME_MVS = 85,
+
+ /*!\brief Codec control function to turn on / off dual interpolation filter
+ * for a sequence, int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable
+ */
+ AV1E_SET_ENABLE_DUAL_FILTER = 86,
+
+ /*!\brief Codec control function to turn on / off delta quantization in chroma
+ * planes for a sequence, int parameter
+ *
+ * - 0 = disable (default)
+ * - 1 = enable
+ */
+ AV1E_SET_ENABLE_CHROMA_DELTAQ = 87,
+
+ /*!\brief Codec control function to turn on / off masked compound usage
+ * (wedge and diff-wtd compound modes) for a sequence, int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_MASKED_COMP = 88,
+
+ /*!\brief Codec control function to turn on / off one sided compound usage
+ * for a sequence, int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_ONESIDED_COMP = 89,
+
+ /*!\brief Codec control function to turn on / off interintra compound
+ * for a sequence, int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_INTERINTRA_COMP = 90,
+
+ /*!\brief Codec control function to turn on / off smooth inter-intra
+ * mode for a sequence, int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_SMOOTH_INTERINTRA = 91,
+
+ /*!\brief Codec control function to turn on / off difference weighted
+ * compound, int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_DIFF_WTD_COMP = 92,
+
+ /*!\brief Codec control function to turn on / off interinter wedge
+ * compound, int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_INTERINTER_WEDGE = 93,
+
+ /*!\brief Codec control function to turn on / off interintra wedge
+ * compound, int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_INTERINTRA_WEDGE = 94,
+
+ /*!\brief Codec control function to turn on / off global motion usage
+ * for a sequence, int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ *
+ * \note Excluded from CONFIG_REALTIME_ONLY build.
+ */
+ AV1E_SET_ENABLE_GLOBAL_MOTION = 95,
+
+ /*!\brief Codec control function to turn on / off warped motion usage
+ * at sequence level, int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ *
+ * \note Excluded from CONFIG_REALTIME_ONLY build.
+ */
+ AV1E_SET_ENABLE_WARPED_MOTION = 96,
+
+ /*!\brief Codec control function to turn on / off warped motion usage
+ * at frame level, int parameter
+ *
+ * \attention If AV1E_SET_ENABLE_WARPED_MOTION is 0, then this flag is
+ * forced to 0.
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ *
+ * \note Excluded from CONFIG_REALTIME_ONLY build.
+ */
+ AV1E_SET_ALLOW_WARPED_MOTION = 97,
+
+ /*!\brief Codec control function to turn on / off filter intra usage at
+ * sequence level, int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_FILTER_INTRA = 98,
+
+ /*!\brief Codec control function to turn on / off smooth intra modes usage,
+ * int parameter
+ *
+ * This will enable or disable usage of smooth, smooth_h and smooth_v intra
+ * modes.
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_SMOOTH_INTRA = 99,
+
+ /*!\brief Codec control function to turn on / off Paeth intra mode usage, int
+ * parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_PAETH_INTRA = 100,
+
+ /*!\brief Codec control function to turn on / off CFL uv intra mode usage, int
+ * parameter
+ *
+ * This will enable or disable usage of chroma-from-luma intra mode.
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_CFL_INTRA = 101,
+
+ /*!\brief Codec control function to turn on / off frame superresolution, int
+ * parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_SUPERRES = 102,
+
+ /*!\brief Codec control function to turn on / off overlay frames for
+ * filtered ALTREF frames, int parameter
+ *
+ * This will enable or disable coding of overlay frames for filtered ALTREF
+ * frames. When set to 0, overlay frames are not used but show existing frame
+ * is used to display the filtered ALTREF frame as is. As a result the decoded
+ * frame rate remains the same as the display frame rate. The default is 1.
+ */
+ AV1E_SET_ENABLE_OVERLAY = 103,
+
+ /*!\brief Codec control function to turn on/off palette mode, int parameter */
+ AV1E_SET_ENABLE_PALETTE = 104,
+
+ /*!\brief Codec control function to turn on/off intra block copy mode, int
+ parameter */
+ AV1E_SET_ENABLE_INTRABC = 105,
+
+ /*!\brief Codec control function to turn on/off intra angle delta, int
+ parameter */
+ AV1E_SET_ENABLE_ANGLE_DELTA = 106,
+
+ /*!\brief Codec control function to set the delta q mode, unsigned int
+ * parameter
+ *
+ * AV1 supports a delta q mode feature, that allows modulating q per
+ * superblock.
+ *
+ * - 0 = deltaq signaling off
+ * - 1 = use modulation to maximize objective quality (default)
+ * - 2 = use modulation for local test
+ * - 3 = use modulation for key frame perceptual quality optimization
+ * - 4 = use modulation for user rating based perceptual quality optimization
+ */
+ AV1E_SET_DELTAQ_MODE = 107,
+
+ /*!\brief Codec control function to turn on/off loopfilter modulation
+ * when delta q modulation is enabled, unsigned int parameter.
+ *
+ * \attention AV1 only supports loopfilter modulation when delta q
+ * modulation is enabled as well.
+ */
+ AV1E_SET_DELTALF_MODE = 108,
+
+ /*!\brief Codec control function to set the single tile decoding mode,
+ * unsigned int parameter
+ *
+ * \attention Only applicable if large scale tiling is on.
+ *
+ * - 0 = single tile decoding is off
+ * - 1 = single tile decoding is on (default)
+ */
+ AV1E_SET_SINGLE_TILE_DECODING = 109,
+
+ /*!\brief Codec control function to enable the extreme motion vector unit
+ * test, unsigned int parameter
+ *
+ * - 0 = off
+ * - 1 = MAX_EXTREME_MV
+ * - 2 = MIN_EXTREME_MV
+ *
+ * \note This is only used in motion vector unit test.
+ */
+ AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST = 110,
+
+ /*!\brief Codec control function to signal picture timing info in the
+ * bitstream, aom_timing_info_type_t parameter. Default is
+ * AOM_TIMING_UNSPECIFIED.
+ */
+ AV1E_SET_TIMING_INFO_TYPE = 111,
+
+ /*!\brief Codec control function to add film grain parameters (one of several
+ * preset types) info in the bitstream, int parameter
+ *
+ Valid range: 0..16, 0 is unknown, 1..16 are test vectors
+ */
+ AV1E_SET_FILM_GRAIN_TEST_VECTOR = 112,
+
+ /*!\brief Codec control function to set the path to the film grain parameters,
+ * const char* parameter
+ */
+ AV1E_SET_FILM_GRAIN_TABLE = 113,
+
+ /*!\brief Sets the noise level, int parameter */
+ AV1E_SET_DENOISE_NOISE_LEVEL = 114,
+
+ /*!\brief Sets the denoisers block size, unsigned int parameter */
+ AV1E_SET_DENOISE_BLOCK_SIZE = 115,
+
+ /*!\brief Sets the chroma subsampling x value, unsigned int parameter */
+ AV1E_SET_CHROMA_SUBSAMPLING_X = 116,
+
+ /*!\brief Sets the chroma subsampling y value, unsigned int parameter */
+ AV1E_SET_CHROMA_SUBSAMPLING_Y = 117,
+
+ /*!\brief Control to use a reduced tx type set, int parameter */
+ AV1E_SET_REDUCED_TX_TYPE_SET = 118,
+
+ /*!\brief Control to use dct only for intra modes, int parameter */
+ AV1E_SET_INTRA_DCT_ONLY = 119,
+
+ /*!\brief Control to use dct only for inter modes, int parameter */
+ AV1E_SET_INTER_DCT_ONLY = 120,
+
+ /*!\brief Control to use default tx type only for intra modes, int parameter
+ */
+ AV1E_SET_INTRA_DEFAULT_TX_ONLY = 121,
+
+ /*!\brief Control to use adaptive quantize_b, int parameter */
+ AV1E_SET_QUANT_B_ADAPT = 122,
+
+ /*!\brief Control to select maximum height for the GF group pyramid structure,
+ * unsigned int parameter
+ *
+ * Valid range: 0..5
+ */
+ AV1E_SET_GF_MAX_PYRAMID_HEIGHT = 123,
+
+ /*!\brief Control to select maximum reference frames allowed per frame, int
+ * parameter
+ *
+ * Valid range: 3..7
+ */
+ AV1E_SET_MAX_REFERENCE_FRAMES = 124,
+
+ /*!\brief Control to use reduced set of single and compound references, int
+ parameter */
+ AV1E_SET_REDUCED_REFERENCE_SET = 125,
+
+ /*!\brief Control to set frequency of the cost updates for coefficients,
+ * unsigned int parameter
+ *
+ * - 0 = update at SB level (default)
+ * - 1 = update at SB row level in tile
+ * - 2 = update at tile level
+ * - 3 = turn off
+ */
+ AV1E_SET_COEFF_COST_UPD_FREQ = 126,
+
+ /*!\brief Control to set frequency of the cost updates for mode, unsigned int
+ * parameter
+ *
+ * - 0 = update at SB level (default)
+ * - 1 = update at SB row level in tile
+ * - 2 = update at tile level
+ * - 3 = turn off
+ */
+ AV1E_SET_MODE_COST_UPD_FREQ = 127,
+
+ /*!\brief Control to set frequency of the cost updates for motion vectors,
+ * unsigned int parameter
+ *
+ * - 0 = update at SB level (default)
+ * - 1 = update at SB row level in tile
+ * - 2 = update at tile level
+ * - 3 = turn off
+ */
+ AV1E_SET_MV_COST_UPD_FREQ = 128,
+
+ /*!\brief Control to set bit mask that specifies which tier each of the 32
+ * possible operating points conforms to, unsigned int parameter
+ *
+ * - 0 = main tier (default)
+ * - 1 = high tier
+ */
+ AV1E_SET_TIER_MASK = 129,
+
+ /*!\brief Control to set minimum compression ratio, unsigned int parameter
+ * Take integer values. If non-zero, encoder will try to keep the compression
+ * ratio of each frame to be higher than the given value divided by 100.
+ * E.g. 850 means minimum compression ratio of 8.5.
+ */
+ AV1E_SET_MIN_CR = 130,
+
+ /* NOTE: enums 145-149 unused */
+
+ /*!\brief Codec control function to set the layer id, aom_svc_layer_id_t*
+ * parameter
+ */
+ AV1E_SET_SVC_LAYER_ID = 131,
+
+ /*!\brief Codec control function to set SVC paramaeters, aom_svc_params_t*
+ * parameter
+ */
+ AV1E_SET_SVC_PARAMS = 132,
+
+ /*!\brief Codec control function to set reference frame config:
+ * the ref_idx and the refresh flags for each buffer slot.
+ * aom_svc_ref_frame_config_t* parameter
+ */
+ AV1E_SET_SVC_REF_FRAME_CONFIG = 133,
+
+ /*!\brief Codec control function to set the path to the VMAF model used when
+ * tuning the encoder for VMAF, const char* parameter
+ */
+ AV1E_SET_VMAF_MODEL_PATH = 134,
+
+ /*!\brief Codec control function to enable EXT_TILE_DEBUG in AV1 encoder,
+ * unsigned int parameter
+ *
+ * - 0 = disable (default)
+ * - 1 = enable
+ *
+ * \note This is only used in lightfield example test.
+ */
+ AV1E_ENABLE_EXT_TILE_DEBUG = 135,
+
+ /*!\brief Codec control function to enable the superblock multipass unit test
+ * in AV1 to ensure that the encoder does not leak state between different
+ * passes. unsigned int parameter.
+ *
+ * - 0 = disable (default)
+ * - 1 = enable
+ *
+ * \note This is only used in sb_multipass unit test.
+ */
+ AV1E_ENABLE_SB_MULTIPASS_UNIT_TEST = 136,
+
+ /*!\brief Control to select minimum height for the GF group pyramid structure,
+ * unsigned int parameter
+ *
+ * Valid values: 0..5
+ */
+ AV1E_SET_GF_MIN_PYRAMID_HEIGHT = 137,
+
+ /*!\brief Control to set average complexity of the corpus in the case of
+ * single pass vbr based on LAP, unsigned int parameter
+ */
+ AV1E_SET_VBR_CORPUS_COMPLEXITY_LAP = 138,
+
+ /*!\brief Control to get baseline gf interval
+ */
+ AV1E_GET_BASELINE_GF_INTERVAL = 139,
+
+ /*\brief Control to set encoding the denoised frame from denoise-noise-level
+ *
+ * - 0 = disabled/encode the original frame
+ * - 1 = enabled/encode the denoised frame (default)
+ */
+ AV1E_SET_ENABLE_DNL_DENOISING = 140,
+
+ /*!\brief Codec control function to turn on / off D45 to D203 intra mode
+ * usage, int parameter
+ *
+ * This will enable or disable usage of D45 to D203 intra modes, which are a
+ * subset of directional modes. This control has no effect if directional
+ * modes are disabled (AV1E_SET_ENABLE_DIRECTIONAL_INTRA set to 0).
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_DIAGONAL_INTRA = 141,
+
+ /*!\brief Control to set frequency of the cost updates for intrabc motion
+ * vectors, unsigned int parameter
+ *
+ * - 0 = update at SB level (default)
+ * - 1 = update at SB row level in tile
+ * - 2 = update at tile level
+ * - 3 = turn off
+ */
+ AV1E_SET_DV_COST_UPD_FREQ = 142,
+
+ /*!\brief Codec control to set the path for partition stats read and write.
+ * const char * parameter.
+ */
+ AV1E_SET_PARTITION_INFO_PATH = 143,
+
+ /*!\brief Codec control to use an external partition model
+ * A set of callback functions is passed through this control
+ * to let the encoder encode with given partitions.
+ */
+ AV1E_SET_EXTERNAL_PARTITION = 144,
+
+ /*!\brief Codec control function to turn on / off directional intra mode
+ * usage, int parameter
+ *
+ * - 0 = disable
+ * - 1 = enable (default)
+ */
+ AV1E_SET_ENABLE_DIRECTIONAL_INTRA = 145,
+
+ /*!\brief Control to turn on / off transform size search.
+ * Note: it can not work with non RD pick mode in real-time encoding,
+ * where the max transform size is only 16x16.
+ * It will be ignored if non RD pick mode is set.
+ *
+ * - 0 = disable, transforms always have the largest possible size
+ * - 1 = enable, search for the best transform size for each block (default)
+ */
+ AV1E_SET_ENABLE_TX_SIZE_SEARCH = 146,
+
+ /*!\brief Codec control function to set reference frame compound prediction.
+ * aom_svc_ref_frame_comp_pred_t* parameter
+ */
+ AV1E_SET_SVC_REF_FRAME_COMP_PRED = 147,
+
+ /*!\brief Set --deltaq-mode strength.
+ *
+ * Valid range: [0, 1000]
+ */
+ AV1E_SET_DELTAQ_STRENGTH = 148,
+
+ /*!\brief Codec control to control loop filter
+ *
+ * - 0 = Loop filter is disabled for all frames
+ * - 1 = Loop filter is enabled for all frames
+ * - 2 = Loop filter is disabled for non-reference frames
+ * - 3 = Loop filter is disabled for the frames with low motion
+ */
+ AV1E_SET_LOOPFILTER_CONTROL = 149,
+
+ /*!\brief Codec control function to get the loopfilter chosen by the encoder,
+ * int* parameter
+ */
+ AOME_GET_LOOPFILTER_LEVEL = 150,
+
+ /*!\brief Codec control to automatically turn off several intra coding tools,
+ * unsigned int parameter
+ * - 0 = do not use the feature
+ * - 1 = enable the automatic decision to turn off several intra tools
+ */
+ AV1E_SET_AUTO_INTRA_TOOLS_OFF = 151,
+
+ /*!\brief Codec control function to set flag for rate control used by external
+ * encoders.
+ * - 1 = Enable rate control for external encoders. This will disable content
+ * dependency in rate control and cyclic refresh.
+ * - 0 = Default. Disable rate control for external encoders.
+ */
+ AV1E_SET_RTC_EXTERNAL_RC = 152,
+
+ /*!\brief Codec control function to enable frame parallel multi-threading
+ * of the encoder, unsigned int parameter
+ *
+ * - 0 = disable (default)
+ * - 1 = enable
+ */
+ AV1E_SET_FP_MT = 153,
+
+ /*!\brief Codec control to enable actual frame parallel encode or
+ * simulation of frame parallel encode in FPMT unit test, unsigned int
+ * parameter
+ *
+ * - 0 = simulate frame parallel encode
+ * - 1 = actual frame parallel encode (default)
+ *
+ * \note This is only used in FPMT unit test.
+ */
+ AV1E_SET_FP_MT_UNIT_TEST = 154,
+
+ /*!\brief Codec control function to get the target sequence level index for
+ * each operating point. int* parameter. There can be at most 32 operating
+ * points. The results will be written into a provided integer array of
+ * sufficient size. If a target level is not set, the result will be 31.
+ * Please refer to https://aomediacodec.github.io/av1-spec/#levels for more
+ * details on level definitions and indices.
+ */
+ AV1E_GET_TARGET_SEQ_LEVEL_IDX = 155,
+
+ /*!\brief Codec control function to get the number of operating points. int*
+ * parameter.
+ */
+ AV1E_GET_NUM_OPERATING_POINTS = 156,
+
+ // Any new encoder control IDs should be added above.
+ // Maximum allowed encoder control ID is 229.
+ // No encoder control ID should be added below.
+};
+
+/*!\brief aom 1-D scaling mode
+ *
+ * This set of constants define 1-D aom scaling modes
+ */
+typedef enum aom_scaling_mode_1d {
+ AOME_NORMAL = 0,
+ AOME_FOURFIVE = 1,
+ AOME_THREEFIVE = 2,
+ AOME_THREEFOUR = 3,
+ AOME_ONEFOUR = 4,
+ AOME_ONEEIGHT = 5,
+ AOME_ONETWO = 6
+} AOM_SCALING_MODE;
+
+/*!\brief Max number of segments
+ *
+ * This is the limit of number of segments allowed within a frame.
+ *
+ * Currently same as "MAX_SEGMENTS" in AV1, the maximum that AV1 supports.
+ *
+ */
+#define AOM_MAX_SEGMENTS 8
+
+/*!\brief aom region of interest map
+ *
+ * These defines the data structures for the region of interest map
+ *
+ * TODO(yaowu): create a unit test for ROI map related APIs
+ *
+ */
+typedef struct aom_roi_map {
+ /*! An id between 0 and 7 for each 8x8 region within a frame. */
+ unsigned char *roi_map;
+ unsigned int rows; /**< Number of rows. */
+ unsigned int cols; /**< Number of columns. */
+ int delta_q[AOM_MAX_SEGMENTS]; /**< Quantizer deltas. */
+ int delta_lf[AOM_MAX_SEGMENTS]; /**< Loop filter deltas. */
+ /*! Static breakout threshold for each segment. */
+ unsigned int static_threshold[AOM_MAX_SEGMENTS];
+} aom_roi_map_t;
+
+/*!\brief aom active region map
+ *
+ * These defines the data structures for active region map
+ *
+ */
+
+typedef struct aom_active_map {
+ /*!\brief specify an on (1) or off (0) each 16x16 region within a frame */
+ unsigned char *active_map;
+ unsigned int rows; /**< number of rows */
+ unsigned int cols; /**< number of cols */
+} aom_active_map_t;
+
+/*!\brief aom image scaling mode
+ *
+ * This defines the data structure for image scaling mode
+ *
+ */
+typedef struct aom_scaling_mode {
+ AOM_SCALING_MODE h_scaling_mode; /**< horizontal scaling mode */
+ AOM_SCALING_MODE v_scaling_mode; /**< vertical scaling mode */
+} aom_scaling_mode_t;
+
+/*!brief AV1 encoder content type */
+typedef enum {
+ AOM_CONTENT_DEFAULT,
+ AOM_CONTENT_SCREEN,
+ AOM_CONTENT_FILM,
+ AOM_CONTENT_INVALID
+} aom_tune_content;
+
+/*!brief AV1 encoder timing info type signaling */
+typedef enum {
+ AOM_TIMING_UNSPECIFIED,
+ AOM_TIMING_EQUAL,
+ AOM_TIMING_DEC_MODEL
+} aom_timing_info_type_t;
+
+/*!\brief Model tuning parameters
+ *
+ * Changes the encoder to tune for certain types of input material.
+ *
+ */
+typedef enum {
+ AOM_TUNE_PSNR = 0,
+ AOM_TUNE_SSIM = 1,
+ /* NOTE: enums 2 and 3 unused */
+ AOM_TUNE_VMAF_WITH_PREPROCESSING = 4,
+ AOM_TUNE_VMAF_WITHOUT_PREPROCESSING = 5,
+ AOM_TUNE_VMAF_MAX_GAIN = 6,
+ AOM_TUNE_VMAF_NEG_MAX_GAIN = 7,
+ AOM_TUNE_BUTTERAUGLI = 8,
+} aom_tune_metric;
+
+/*!\brief Distortion metric to use for RD optimization.
+ *
+ * Changes the encoder to use a different distortion metric for RD search. Note
+ * that this value operates on a "lower level" compared to aom_tune_metric - it
+ * affects the distortion metric inside a block, while aom_tune_metric only
+ * affects RD across blocks.
+ *
+ */
+typedef enum {
+ // Use PSNR for in-block rate-distortion optimization.
+ AOM_DIST_METRIC_PSNR,
+ // Use quantization matrix-weighted PSNR for in-block rate-distortion
+ // optimization. If --enable-qm=1 is not specified, this falls back to
+ // behaving in the same way as AOM_DIST_METRIC_PSNR.
+ AOM_DIST_METRIC_QM_PSNR,
+} aom_dist_metric;
+
+#define AOM_MAX_LAYERS 32 /**< Max number of layers */
+#define AOM_MAX_SS_LAYERS 4 /**< Max number of spatial layers */
+#define AOM_MAX_TS_LAYERS 8 /**< Max number of temporal layers */
+
+/*!brief Struct for spatial and temporal layer ID */
+typedef struct aom_svc_layer_id {
+ int spatial_layer_id; /**< Spatial layer ID */
+ int temporal_layer_id; /**< Temporal layer ID */
+} aom_svc_layer_id_t;
+
+/*!brief Parameter type for SVC */
+typedef struct aom_svc_params {
+ int number_spatial_layers; /**< Number of spatial layers */
+ int number_temporal_layers; /**< Number of temporal layers */
+ int max_quantizers[AOM_MAX_LAYERS]; /**< Max Q for each layer */
+ int min_quantizers[AOM_MAX_LAYERS]; /**< Min Q for each layer */
+ int scaling_factor_num[AOM_MAX_SS_LAYERS]; /**< Scaling factor-numerator */
+ int scaling_factor_den[AOM_MAX_SS_LAYERS]; /**< Scaling factor-denominator */
+ /*! Target bitrate for each layer */
+ int layer_target_bitrate[AOM_MAX_LAYERS];
+ /*! Frame rate factor for each temporal layer */
+ int framerate_factor[AOM_MAX_TS_LAYERS];
+} aom_svc_params_t;
+
+/*!brief Parameters for setting ref frame config */
+typedef struct aom_svc_ref_frame_config {
+ // 7 references: LAST_FRAME (0), LAST2_FRAME(1), LAST3_FRAME(2),
+ // GOLDEN_FRAME(3), BWDREF_FRAME(4), ALTREF2_FRAME(5), ALTREF_FRAME(6).
+ int reference[7]; /**< Reference flag for each of the 7 references. */
+ /*! Buffer slot index for each of 7 references. */
+ int ref_idx[7];
+ int refresh[8]; /**< Refresh flag for each of the 8 slots. */
+} aom_svc_ref_frame_config_t;
+
+/*!brief Parameters for setting ref frame compound prediction */
+typedef struct aom_svc_ref_frame_comp_pred {
+ // Use compound prediction for the ref_frame pairs GOLDEN_LAST (0),
+ // LAST2_LAST (1), and ALTREF_LAST (2).
+ int use_comp_pred[3]; /**= 256.
+ *
+ * \sa #aom_codec_control(aom_codec_ctx_t *ctx, int ctrl_id, ...)
+ */
+enum aom_dec_control_id {
+ /*!\brief Codec control function to get info on which reference frames were
+ * updated by the last decode, int* parameter
+ */
+ AOMD_GET_LAST_REF_UPDATES = AOM_DECODER_CTRL_ID_START,
+
+ /*!\brief Codec control function to check if the indicated frame is
+ corrupted, int* parameter
+ */
+ AOMD_GET_FRAME_CORRUPTED,
+
+ /*!\brief Codec control function to get info on which reference frames were
+ * used by the last decode, int* parameter
+ */
+ AOMD_GET_LAST_REF_USED,
+
+ /*!\brief Codec control function to get the dimensions that the current
+ * frame is decoded at, int* parameter
+ *
+ * This may be different to the intended display size for the frame as
+ * specified in the wrapper or frame header (see AV1D_GET_DISPLAY_SIZE).
+ */
+ AV1D_GET_FRAME_SIZE,
+
+ /*!\brief Codec control function to get the current frame's intended display
+ * dimensions (as specified in the wrapper or frame header), int* parameter
+ *
+ * This may be different to the decoded dimensions of this frame (see
+ * AV1D_GET_FRAME_SIZE).
+ */
+ AV1D_GET_DISPLAY_SIZE,
+
+ /*!\brief Codec control function to get the bit depth of the stream,
+ * unsigned int* parameter
+ */
+ AV1D_GET_BIT_DEPTH,
+
+ /*!\brief Codec control function to get the image format of the stream,
+ * aom_img_fmt_t* parameter
+ */
+ AV1D_GET_IMG_FORMAT,
+
+ /*!\brief Codec control function to get the size of the tile, unsigned int*
+ * parameter
+ */
+ AV1D_GET_TILE_SIZE,
+
+ /*!\brief Codec control function to get the tile count in a tile list,
+ * unsigned int* parameter
+ */
+ AV1D_GET_TILE_COUNT,
+
+ /*!\brief Codec control function to set the byte alignment of the planes in
+ * the reference buffers, int parameter
+ *
+ * Valid values are power of 2, from 32 to 1024. A value of 0 sets
+ * legacy alignment. I.e. Y plane is aligned to 32 bytes, U plane directly
+ * follows Y plane, and V plane directly follows U plane. Default value is 0.
+ */
+ AV1_SET_BYTE_ALIGNMENT,
+
+ /*!\brief Codec control function to invert the decoding order to from right to
+ * left, int parameter
+ *
+ * The function is used in a test to confirm the decoding independence of tile
+ * columns. The function may be used in application where this order
+ * of decoding is desired. int parameter
+ *
+ * TODO(yaowu): Rework the unit test that uses this control, and in a future
+ * release, this test-only control shall be removed.
+ */
+ AV1_INVERT_TILE_DECODE_ORDER,
+
+ /*!\brief Codec control function to set the skip loop filter flag, int
+ * parameter
+ *
+ * Valid values are integers. The decoder will skip the loop filter
+ * when its value is set to nonzero. If the loop filter is skipped the
+ * decoder may accumulate decode artifacts. The default value is 0.
+ */
+ AV1_SET_SKIP_LOOP_FILTER,
+
+ /*!\brief Codec control function to retrieve a pointer to the Accounting
+ * struct, takes Accounting** as parameter
+ *
+ * If called before a frame has been decoded, this returns AOM_CODEC_ERROR.
+ * The caller should ensure that AOM_CODEC_OK is returned before attempting
+ * to dereference the Accounting pointer.
+ *
+ * \attention When configured with -DCONFIG_ACCOUNTING=0, the default, this
+ * returns AOM_CODEC_INCAPABLE.
+ */
+ AV1_GET_ACCOUNTING,
+
+ /*!\brief Codec control function to get last decoded frame quantizer,
+ * int* parameter
+ *
+ * Returned value uses internal quantizer scale defined by the codec.
+ */
+ AOMD_GET_LAST_QUANTIZER,
+
+ /*!\brief Codec control function to set the range of tile decoding, int
+ * parameter
+ *
+ * A value that is greater and equal to zero indicates only the specific
+ * row/column is decoded. A value that is -1 indicates the whole row/column
+ * is decoded. A special case is both values are -1 that means the whole
+ * frame is decoded.
+ */
+ AV1_SET_DECODE_TILE_ROW,
+ AV1_SET_DECODE_TILE_COL,
+
+ /*!\brief Codec control function to set the tile coding mode, unsigned int
+ * parameter
+ *
+ * - 0 = tiles are coded in normal tile mode
+ * - 1 = tiles are coded in large-scale tile mode
+ */
+ AV1_SET_TILE_MODE,
+
+ /*!\brief Codec control function to get the frame header information of an
+ * encoded frame, aom_tile_data* parameter
+ */
+ AV1D_GET_FRAME_HEADER_INFO,
+
+ /*!\brief Codec control function to get the start address and size of a
+ * tile in the coded bitstream, aom_tile_data* parameter.
+ */
+ AV1D_GET_TILE_DATA,
+
+ /*!\brief Codec control function to set the external references' pointers in
+ * the decoder, av1_ext_ref_frame_t* parameter.
+ *
+ * This is used while decoding the tile list OBU in large-scale tile coding
+ * mode.
+ */
+ AV1D_SET_EXT_REF_PTR,
+
+ /*!\brief Codec control function to enable the ext-tile software debug and
+ * testing code in the decoder, unsigned int parameter
+ */
+ AV1D_EXT_TILE_DEBUG,
+
+ /*!\brief Codec control function to enable the row based multi-threading of
+ * decoding, unsigned int parameter
+ *
+ * - 0 = disabled
+ * - 1 = enabled (default)
+ */
+ AV1D_SET_ROW_MT,
+
+ /*!\brief Codec control function to indicate whether bitstream is in
+ * Annex-B format, unsigned int parameter
+ */
+ AV1D_SET_IS_ANNEXB,
+
+ /*!\brief Codec control function to indicate which operating point to use,
+ * int parameter
+ *
+ * A scalable stream may define multiple operating points, each of which
+ * defines a set of temporal and spatial layers to be processed. The
+ * operating point index may take a value between 0 and
+ * operating_points_cnt_minus_1 (which is at most 31).
+ */
+ AV1D_SET_OPERATING_POINT,
+
+ /*!\brief Codec control function to indicate whether to output one frame per
+ * temporal unit (the default), or one frame per spatial layer, int parameter
+ *
+ * In a scalable stream, each temporal unit corresponds to a single "frame"
+ * of video, and within a temporal unit there may be multiple spatial layers
+ * with different versions of that frame.
+ * For video playback, only the highest-quality version (within the
+ * selected operating point) is needed, but for some use cases it is useful
+ * to have access to multiple versions of a frame when they are available.
+ */
+ AV1D_SET_OUTPUT_ALL_LAYERS,
+
+ /*!\brief Codec control function to set an aom_inspect_cb callback that is
+ * invoked each time a frame is decoded, aom_inspect_init* parameter
+ *
+ * \attention When configured with -DCONFIG_INSPECTION=0, the default, this
+ * returns AOM_CODEC_INCAPABLE.
+ */
+ AV1_SET_INSPECTION_CALLBACK,
+
+ /*!\brief Codec control function to set the skip film grain flag, int
+ * parameter
+ *
+ * Valid values are integers. The decoder will skip the film grain when its
+ * value is set to nonzero. The default value is 0.
+ */
+ AV1D_SET_SKIP_FILM_GRAIN,
+
+ /*!\brief Codec control function to check the presence of forward key frames,
+ * int* parameter
+ */
+ AOMD_GET_FWD_KF_PRESENT,
+
+ /*!\brief Codec control function to get the frame flags of the previous frame
+ * decoded, int* parameter
+ *
+ * This will return a flag of type aom_codec_frame_flags_t.
+ */
+ AOMD_GET_FRAME_FLAGS,
+
+ /*!\brief Codec control function to check the presence of altref frames, int*
+ * parameter
+ */
+ AOMD_GET_ALTREF_PRESENT,
+
+ /*!\brief Codec control function to get tile information of the previous frame
+ * decoded, aom_tile_info* parameter
+ *
+ * This will return a struct of type aom_tile_info.
+ */
+ AOMD_GET_TILE_INFO,
+
+ /*!\brief Codec control function to get screen content tools information,
+ * aom_screen_content_tools_info* parameter
+ *
+ * It returns a struct of type aom_screen_content_tools_info, which contains
+ * the header flags allow_screen_content_tools, allow_intrabc, and
+ * force_integer_mv.
+ */
+ AOMD_GET_SCREEN_CONTENT_TOOLS_INFO,
+
+ /*!\brief Codec control function to get the still picture coding information,
+ * aom_still_picture_info* parameter
+ */
+ AOMD_GET_STILL_PICTURE,
+
+ /*!\brief Codec control function to get superblock size,
+ * aom_superblock_size_t* parameter
+ *
+ * It returns an enum, indicating the superblock size read from the sequence
+ * header(0 for BLOCK_64X64 and 1 for BLOCK_128X128)
+ */
+ AOMD_GET_SB_SIZE,
+
+ /*!\brief Codec control function to check if the previous frame
+ * decoded has show existing frame flag set, int* parameter
+ */
+ AOMD_GET_SHOW_EXISTING_FRAME_FLAG,
+
+ /*!\brief Codec control function to get the S_FRAME coding information,
+ * aom_s_frame_info* parameter
+ */
+ AOMD_GET_S_FRAME_INFO,
+
+ /*!\brief Codec control function to get the show frame flag, int* parameter
+ */
+ AOMD_GET_SHOW_FRAME_FLAG,
+
+ /*!\brief Codec control function to get the base q index of a frame, int*
+ * parameter
+ */
+ AOMD_GET_BASE_Q_IDX,
+
+ /*!\brief Codec control function to get the order hint of a frame, unsigned
+ * int* parameter
+ */
+ AOMD_GET_ORDER_HINT,
+
+ /*!\brief Codec control function to get the info of a 4x4 block.
+ * Parameters: int mi_row, int mi_col, and MB_MODE_INFO*.
+ *
+ * \note This only returns a shallow copy, so all pointer members should not
+ * be used.
+ */
+ AV1D_GET_MI_INFO,
+};
+
+/*!\cond */
+/*!\brief AOM decoder control function parameter type
+ *
+ * Defines the data types that AOMD control functions take.
+ *
+ * \note Additional common controls are defined in aom.h.
+ *
+ * \note For each control ID "X", a macro-define of
+ * AOM_CTRL_X is provided. It is used at compile time to determine
+ * if the control ID is supported by the libaom library available,
+ * when the libaom version cannot be controlled.
+ */
+AOM_CTRL_USE_TYPE(AOMD_GET_LAST_REF_UPDATES, int *)
+#define AOM_CTRL_AOMD_GET_LAST_REF_UPDATES
+
+AOM_CTRL_USE_TYPE(AOMD_GET_FRAME_CORRUPTED, int *)
+#define AOM_CTRL_AOMD_GET_FRAME_CORRUPTED
+
+AOM_CTRL_USE_TYPE(AOMD_GET_LAST_REF_USED, int *)
+#define AOM_CTRL_AOMD_GET_LAST_REF_USED
+
+AOM_CTRL_USE_TYPE(AV1D_GET_FRAME_SIZE, int *)
+#define AOM_CTRL_AV1D_GET_FRAME_SIZE
+
+AOM_CTRL_USE_TYPE(AV1D_GET_DISPLAY_SIZE, int *)
+#define AOM_CTRL_AV1D_GET_DISPLAY_SIZE
+
+AOM_CTRL_USE_TYPE(AV1D_GET_BIT_DEPTH, unsigned int *)
+#define AOM_CTRL_AV1D_GET_BIT_DEPTH
+
+AOM_CTRL_USE_TYPE(AV1D_GET_IMG_FORMAT, aom_img_fmt_t *)
+#define AOM_CTRL_AV1D_GET_IMG_FORMAT
+
+AOM_CTRL_USE_TYPE(AV1D_GET_TILE_SIZE, unsigned int *)
+#define AOM_CTRL_AV1D_GET_TILE_SIZE
+
+AOM_CTRL_USE_TYPE(AV1D_GET_TILE_COUNT, unsigned int *)
+#define AOM_CTRL_AV1D_GET_TILE_COUNT
+
+AOM_CTRL_USE_TYPE(AV1_INVERT_TILE_DECODE_ORDER, int)
+#define AOM_CTRL_AV1_INVERT_TILE_DECODE_ORDER
+
+AOM_CTRL_USE_TYPE(AV1_SET_SKIP_LOOP_FILTER, int)
+#define AOM_CTRL_AV1_SET_SKIP_LOOP_FILTER
+
+AOM_CTRL_USE_TYPE(AV1_GET_ACCOUNTING, Accounting **)
+#define AOM_CTRL_AV1_GET_ACCOUNTING
+
+AOM_CTRL_USE_TYPE(AOMD_GET_LAST_QUANTIZER, int *)
+#define AOM_CTRL_AOMD_GET_LAST_QUANTIZER
+
+AOM_CTRL_USE_TYPE(AV1_SET_DECODE_TILE_ROW, int)
+#define AOM_CTRL_AV1_SET_DECODE_TILE_ROW
+
+AOM_CTRL_USE_TYPE(AV1_SET_DECODE_TILE_COL, int)
+#define AOM_CTRL_AV1_SET_DECODE_TILE_COL
+
+AOM_CTRL_USE_TYPE(AV1_SET_TILE_MODE, unsigned int)
+#define AOM_CTRL_AV1_SET_TILE_MODE
+
+AOM_CTRL_USE_TYPE(AV1D_GET_FRAME_HEADER_INFO, aom_tile_data *)
+#define AOM_CTRL_AV1D_GET_FRAME_HEADER_INFO
+
+AOM_CTRL_USE_TYPE(AV1D_GET_TILE_DATA, aom_tile_data *)
+#define AOM_CTRL_AV1D_GET_TILE_DATA
+
+AOM_CTRL_USE_TYPE(AV1D_SET_EXT_REF_PTR, av1_ext_ref_frame_t *)
+#define AOM_CTRL_AV1D_SET_EXT_REF_PTR
+
+AOM_CTRL_USE_TYPE(AV1D_EXT_TILE_DEBUG, unsigned int)
+#define AOM_CTRL_AV1D_EXT_TILE_DEBUG
+
+AOM_CTRL_USE_TYPE(AV1D_SET_ROW_MT, unsigned int)
+#define AOM_CTRL_AV1D_SET_ROW_MT
+
+AOM_CTRL_USE_TYPE(AV1D_SET_IS_ANNEXB, unsigned int)
+#define AOM_CTRL_AV1D_SET_IS_ANNEXB
+
+AOM_CTRL_USE_TYPE(AV1D_SET_OPERATING_POINT, int)
+#define AOM_CTRL_AV1D_SET_OPERATING_POINT
+
+AOM_CTRL_USE_TYPE(AV1D_SET_OUTPUT_ALL_LAYERS, int)
+#define AOM_CTRL_AV1D_SET_OUTPUT_ALL_LAYERS
+
+AOM_CTRL_USE_TYPE(AV1_SET_INSPECTION_CALLBACK, aom_inspect_init *)
+#define AOM_CTRL_AV1_SET_INSPECTION_CALLBACK
+
+AOM_CTRL_USE_TYPE(AV1D_SET_SKIP_FILM_GRAIN, int)
+#define AOM_CTRL_AV1D_SET_SKIP_FILM_GRAIN
+
+AOM_CTRL_USE_TYPE(AOMD_GET_FWD_KF_PRESENT, int *)
+#define AOM_CTRL_AOMD_GET_FWD_KF_PRESENT
+
+AOM_CTRL_USE_TYPE(AOMD_GET_FRAME_FLAGS, int *)
+#define AOM_CTRL_AOMD_GET_FRAME_FLAGS
+
+AOM_CTRL_USE_TYPE(AOMD_GET_ALTREF_PRESENT, int *)
+#define AOM_CTRL_AOMD_GET_ALTREF_PRESENT
+
+AOM_CTRL_USE_TYPE(AOMD_GET_TILE_INFO, aom_tile_info *)
+#define AOM_CTRL_AOMD_GET_TILE_INFO
+
+AOM_CTRL_USE_TYPE(AOMD_GET_SCREEN_CONTENT_TOOLS_INFO,
+ aom_screen_content_tools_info *)
+#define AOM_CTRL_AOMD_GET_SCREEN_CONTENT_TOOLS_INFO
+
+AOM_CTRL_USE_TYPE(AOMD_GET_STILL_PICTURE, aom_still_picture_info *)
+#define AOM_CTRL_AOMD_GET_STILL_PICTURE
+
+AOM_CTRL_USE_TYPE(AOMD_GET_SB_SIZE, aom_superblock_size_t *)
+#define AOMD_CTRL_AOMD_GET_SB_SIZE
+
+AOM_CTRL_USE_TYPE(AOMD_GET_SHOW_EXISTING_FRAME_FLAG, int *)
+#define AOMD_CTRL_AOMD_GET_SHOW_EXISTING_FRAME_FLAG
+
+AOM_CTRL_USE_TYPE(AOMD_GET_S_FRAME_INFO, aom_s_frame_info *)
+#define AOMD_CTRL_AOMD_GET_S_FRAME_INFO
+
+AOM_CTRL_USE_TYPE(AOMD_GET_SHOW_FRAME_FLAG, int *)
+#define AOM_CTRL_AOMD_GET_SHOW_FRAME_FLAG
+
+AOM_CTRL_USE_TYPE(AOMD_GET_BASE_Q_IDX, int *)
+#define AOM_CTRL_AOMD_GET_BASE_Q_IDX
+
+AOM_CTRL_USE_TYPE(AOMD_GET_ORDER_HINT, unsigned int *)
+#define AOM_CTRL_AOMD_GET_ORDER_HINT
+
+// The AOM_CTRL_USE_TYPE macro can't be used with AV1D_GET_MI_INFO because
+// AV1D_GET_MI_INFO takes more than one parameter.
+#define AOM_CTRL_AV1D_GET_MI_INFO
+/*!\endcond */
+/*! @} - end defgroup aom_decoder */
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // AOM_AOM_AOMDX_H_
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/cgif.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/cgif.h
new file mode 100644
index 0000000..4ad4747
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/cgif.h
@@ -0,0 +1,80 @@
+#ifndef CGIF_H
+#define CGIF_H
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// flags to set the GIF/frame-attributes
+#define CGIF_ATTR_IS_ANIMATED (1uL << 1) // make an animated GIF (default is non-animated GIF)
+#define CGIF_ATTR_NO_GLOBAL_TABLE (1uL << 2) // disable global color table (global color table is default)
+#define CGIF_ATTR_HAS_TRANSPARENCY (1uL << 3) // first entry in color table contains transparency (alpha channel)
+#define CGIF_ATTR_NO_LOOP (1uL << 4) // don't loop a GIF animation: only play it one time.
+#define CGIF_FRAME_ATTR_USE_LOCAL_TABLE (1uL << 0) // use a local color table for a frame (local color table is not used by default)
+#define CGIF_FRAME_ATTR_HAS_ALPHA (1uL << 1) // alpha channel index provided by user (transIndex field)
+#define CGIF_FRAME_ATTR_HAS_SET_TRANS (1uL << 2) // transparency setting provided by user (transIndex field)
+#define CGIF_FRAME_ATTR_INTERLACED (1uL << 3) // encode frame interlaced (default is not interlaced)
+// flags to decrease GIF-size
+#define CGIF_FRAME_GEN_USE_TRANSPARENCY (1uL << 0) // use transparency optimization (setting pixels identical to previous frame transparent)
+#define CGIF_FRAME_GEN_USE_DIFF_WINDOW (1uL << 1) // do encoding just for the sub-window that has changed from previous frame
+
+#define CGIF_INFINITE_LOOP (0x0000uL) // for animated GIF: 0 specifies infinite loop
+
+typedef enum {
+ CGIF_ERROR = -1, // something unspecified failed
+ CGIF_OK = 0, // everything OK
+ CGIF_EWRITE, // writing GIF data failed
+ CGIF_EALLOC, // allocating memory failed
+ CGIF_ECLOSE, // final call to fclose failed
+ CGIF_EOPEN, // failed to open output file
+ CGIF_EINDEX, // invalid index in image data provided by user
+ // internal section (values subject to change)
+ CGIF_PENDING,
+} cgif_result;
+
+typedef struct st_gif CGIF; // struct for the full GIF
+typedef struct st_gifconfig CGIF_Config; // global cofinguration parameters of the GIF
+typedef struct st_frameconfig CGIF_FrameConfig; // local configuration parameters for a frame
+
+typedef int cgif_write_fn(void* pContext, const uint8_t* pData, const size_t numBytes); // callback function for stream-based output
+
+// prototypes
+CGIF* cgif_newgif (CGIF_Config* pConfig); // creates a new GIF (returns pointer to new GIF or NULL on error)
+int cgif_addframe (CGIF* pGIF, CGIF_FrameConfig* pConfig); // adds the next frame to an existing GIF (returns 0 on success)
+int cgif_close (CGIF* pGIF); // close file and free allocated memory (returns 0 on success)
+
+// CGIF_Config type (parameters passed by user)
+// note: must stay AS IS for backward compatibility
+struct st_gifconfig {
+ uint8_t* pGlobalPalette; // global color table of the GIF
+ const char* path; // path of the GIF to be created, mutually exclusive with pWriteFn
+ uint32_t attrFlags; // fixed attributes of the GIF (e.g. whether it is animated or not)
+ uint32_t genFlags; // flags that determine how the GIF is generated (e.g. optimization)
+ uint16_t width; // width of each frame in the GIF
+ uint16_t height; // height of each frame in the GIF
+ uint16_t numGlobalPaletteEntries; // size of the global color table
+ uint16_t numLoops; // number of repetitons of an animated GIF (set to INFINITE_LOOP for infinite loop)
+ cgif_write_fn *pWriteFn; // callback function for chunks of output data, mutually exclusive with path
+ void* pContext; // opaque pointer passed as the first parameter to pWriteFn
+};
+
+// CGIF_FrameConfig type (parameters passed by user)
+// note: must stay AS IS for backward compatibility
+struct st_frameconfig {
+ uint8_t* pLocalPalette; // local color table of a frame
+ uint8_t* pImageData; // image data to be encoded
+ uint32_t attrFlags; // fixed attributes of the GIF frame
+ uint32_t genFlags; // flags that determine how the GIF frame is created (e.g. optimization)
+ uint16_t delay; // delay before the next frame is shown (units of 0.01 s)
+ uint16_t numLocalPaletteEntries; // size of the local color table
+ uint8_t transIndex; // introduced with V0.2.0
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CGIF_H
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/expat.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/expat.h
new file mode 100644
index 0000000..1c83563
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/expat.h
@@ -0,0 +1,1064 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000 Clark Cooper
+ Copyright (c) 2000-2005 Fred L. Drake, Jr.
+ Copyright (c) 2001-2002 Greg Stein
+ Copyright (c) 2002-2016 Karl Waclawek
+ Copyright (c) 2016-2022 Sebastian Pipping
+ Copyright (c) 2016 Cristian Rodríguez
+ Copyright (c) 2016 Thomas Beutlich
+ Copyright (c) 2017 Rhodri James
+ Copyright (c) 2022 Thijs Schreijer
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef Expat_INCLUDED
+#define Expat_INCLUDED 1
+
+#include
+#include "expat_external.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct XML_ParserStruct;
+typedef struct XML_ParserStruct *XML_Parser;
+
+typedef unsigned char XML_Bool;
+#define XML_TRUE ((XML_Bool)1)
+#define XML_FALSE ((XML_Bool)0)
+
+/* The XML_Status enum gives the possible return values for several
+ API functions. The preprocessor #defines are included so this
+ stanza can be added to code that still needs to support older
+ versions of Expat 1.95.x:
+
+ #ifndef XML_STATUS_OK
+ #define XML_STATUS_OK 1
+ #define XML_STATUS_ERROR 0
+ #endif
+
+ Otherwise, the #define hackery is quite ugly and would have been
+ dropped.
+*/
+enum XML_Status {
+ XML_STATUS_ERROR = 0,
+#define XML_STATUS_ERROR XML_STATUS_ERROR
+ XML_STATUS_OK = 1,
+#define XML_STATUS_OK XML_STATUS_OK
+ XML_STATUS_SUSPENDED = 2
+#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED
+};
+
+enum XML_Error {
+ XML_ERROR_NONE,
+ XML_ERROR_NO_MEMORY,
+ XML_ERROR_SYNTAX,
+ XML_ERROR_NO_ELEMENTS,
+ XML_ERROR_INVALID_TOKEN,
+ XML_ERROR_UNCLOSED_TOKEN,
+ XML_ERROR_PARTIAL_CHAR,
+ XML_ERROR_TAG_MISMATCH,
+ XML_ERROR_DUPLICATE_ATTRIBUTE,
+ XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
+ XML_ERROR_PARAM_ENTITY_REF,
+ XML_ERROR_UNDEFINED_ENTITY,
+ XML_ERROR_RECURSIVE_ENTITY_REF,
+ XML_ERROR_ASYNC_ENTITY,
+ XML_ERROR_BAD_CHAR_REF,
+ XML_ERROR_BINARY_ENTITY_REF,
+ XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
+ XML_ERROR_MISPLACED_XML_PI,
+ XML_ERROR_UNKNOWN_ENCODING,
+ XML_ERROR_INCORRECT_ENCODING,
+ XML_ERROR_UNCLOSED_CDATA_SECTION,
+ XML_ERROR_EXTERNAL_ENTITY_HANDLING,
+ XML_ERROR_NOT_STANDALONE,
+ XML_ERROR_UNEXPECTED_STATE,
+ XML_ERROR_ENTITY_DECLARED_IN_PE,
+ XML_ERROR_FEATURE_REQUIRES_XML_DTD,
+ XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING,
+ /* Added in 1.95.7. */
+ XML_ERROR_UNBOUND_PREFIX,
+ /* Added in 1.95.8. */
+ XML_ERROR_UNDECLARING_PREFIX,
+ XML_ERROR_INCOMPLETE_PE,
+ XML_ERROR_XML_DECL,
+ XML_ERROR_TEXT_DECL,
+ XML_ERROR_PUBLICID,
+ XML_ERROR_SUSPENDED,
+ XML_ERROR_NOT_SUSPENDED,
+ XML_ERROR_ABORTED,
+ XML_ERROR_FINISHED,
+ XML_ERROR_SUSPEND_PE,
+ /* Added in 2.0. */
+ XML_ERROR_RESERVED_PREFIX_XML,
+ XML_ERROR_RESERVED_PREFIX_XMLNS,
+ XML_ERROR_RESERVED_NAMESPACE_URI,
+ /* Added in 2.2.1. */
+ XML_ERROR_INVALID_ARGUMENT,
+ /* Added in 2.3.0. */
+ XML_ERROR_NO_BUFFER,
+ /* Added in 2.4.0. */
+ XML_ERROR_AMPLIFICATION_LIMIT_BREACH
+};
+
+enum XML_Content_Type {
+ XML_CTYPE_EMPTY = 1,
+ XML_CTYPE_ANY,
+ XML_CTYPE_MIXED,
+ XML_CTYPE_NAME,
+ XML_CTYPE_CHOICE,
+ XML_CTYPE_SEQ
+};
+
+enum XML_Content_Quant {
+ XML_CQUANT_NONE,
+ XML_CQUANT_OPT,
+ XML_CQUANT_REP,
+ XML_CQUANT_PLUS
+};
+
+/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be
+ XML_CQUANT_NONE, and the other fields will be zero or NULL.
+ If type == XML_CTYPE_MIXED, then quant will be NONE or REP and
+ numchildren will contain number of elements that may be mixed in
+ and children point to an array of XML_Content cells that will be
+ all of XML_CTYPE_NAME type with no quantification.
+
+ If type == XML_CTYPE_NAME, then the name points to the name, and
+ the numchildren field will be zero and children will be NULL. The
+ quant fields indicates any quantifiers placed on the name.
+
+ CHOICE and SEQ will have name NULL, the number of children in
+ numchildren and children will point, recursively, to an array
+ of XML_Content cells.
+
+ The EMPTY, ANY, and MIXED types will only occur at top level.
+*/
+
+typedef struct XML_cp XML_Content;
+
+struct XML_cp {
+ enum XML_Content_Type type;
+ enum XML_Content_Quant quant;
+ XML_Char *name;
+ unsigned int numchildren;
+ XML_Content *children;
+};
+
+/* This is called for an element declaration. See above for
+ description of the model argument. It's the user code's responsibility
+ to free model when finished with it. See XML_FreeContentModel.
+ There is no need to free the model from the handler, it can be kept
+ around and freed at a later stage.
+*/
+typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData,
+ const XML_Char *name,
+ XML_Content *model);
+
+XMLPARSEAPI(void)
+XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl);
+
+/* The Attlist declaration handler is called for *each* attribute. So
+ a single Attlist declaration with multiple attributes declared will
+ generate multiple calls to this handler. The "default" parameter
+ may be NULL in the case of the "#IMPLIED" or "#REQUIRED"
+ keyword. The "isrequired" parameter will be true and the default
+ value will be NULL in the case of "#REQUIRED". If "isrequired" is
+ true and default is non-NULL, then this is a "#FIXED" default.
+*/
+typedef void(XMLCALL *XML_AttlistDeclHandler)(
+ void *userData, const XML_Char *elname, const XML_Char *attname,
+ const XML_Char *att_type, const XML_Char *dflt, int isrequired);
+
+XMLPARSEAPI(void)
+XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl);
+
+/* The XML declaration handler is called for *both* XML declarations
+ and text declarations. The way to distinguish is that the version
+ parameter will be NULL for text declarations. The encoding
+ parameter may be NULL for XML declarations. The standalone
+ parameter will be -1, 0, or 1 indicating respectively that there
+ was no standalone parameter in the declaration, that it was given
+ as no, or that it was given as yes.
+*/
+typedef void(XMLCALL *XML_XmlDeclHandler)(void *userData,
+ const XML_Char *version,
+ const XML_Char *encoding,
+ int standalone);
+
+XMLPARSEAPI(void)
+XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler xmldecl);
+
+typedef struct {
+ void *(*malloc_fcn)(size_t size);
+ void *(*realloc_fcn)(void *ptr, size_t size);
+ void (*free_fcn)(void *ptr);
+} XML_Memory_Handling_Suite;
+
+/* Constructs a new parser; encoding is the encoding specified by the
+ external protocol or NULL if there is none specified.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreate(const XML_Char *encoding);
+
+/* Constructs a new parser and namespace processor. Element type
+ names and attribute names that belong to a namespace will be
+ expanded; unprefixed attribute names are never expanded; unprefixed
+ element type names are expanded only if there is a default
+ namespace. The expanded name is the concatenation of the namespace
+ URI, the namespace separator character, and the local part of the
+ name. If the namespace separator is '\0' then the namespace URI
+ and the local part will be concatenated without any separator.
+ It is a programming error to use the separator '\0' with namespace
+ triplets (see XML_SetReturnNSTriplet).
+ If a namespace separator is chosen that can be part of a URI or
+ part of an XML name, splitting an expanded name back into its
+ 1, 2 or 3 original parts on application level in the element handler
+ may end up vulnerable, so these are advised against; sane choices for
+ a namespace separator are e.g. '\n' (line feed) and '|' (pipe).
+
+ Note that Expat does not validate namespace URIs (beyond encoding)
+ against RFC 3986 today (and is not required to do so with regard to
+ the XML 1.0 namespaces specification) but it may start doing that
+ in future releases. Before that, an application using Expat must
+ be ready to receive namespace URIs containing non-URI characters.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
+
+/* Constructs a new parser using the memory management suite referred to
+ by memsuite. If memsuite is NULL, then use the standard library memory
+ suite. If namespaceSeparator is non-NULL it creates a parser with
+ namespace processing as described above. The character pointed at
+ will serve as the namespace separator.
+
+ All further memory operations used for the created parser will come from
+ the given suite.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ParserCreate_MM(const XML_Char *encoding,
+ const XML_Memory_Handling_Suite *memsuite,
+ const XML_Char *namespaceSeparator);
+
+/* Prepare a parser object to be re-used. This is particularly
+ valuable when memory allocation overhead is disproportionately high,
+ such as when a large number of small documnents need to be parsed.
+ All handlers are cleared from the parser, except for the
+ unknownEncodingHandler. The parser's external state is re-initialized
+ except for the values of ns and ns_triplets.
+
+ Added in Expat 1.95.3.
+*/
+XMLPARSEAPI(XML_Bool)
+XML_ParserReset(XML_Parser parser, const XML_Char *encoding);
+
+/* atts is array of name/value pairs, terminated by 0;
+ names and values are 0 terminated.
+*/
+typedef void(XMLCALL *XML_StartElementHandler)(void *userData,
+ const XML_Char *name,
+ const XML_Char **atts);
+
+typedef void(XMLCALL *XML_EndElementHandler)(void *userData,
+ const XML_Char *name);
+
+/* s is not 0 terminated. */
+typedef void(XMLCALL *XML_CharacterDataHandler)(void *userData,
+ const XML_Char *s, int len);
+
+/* target and data are 0 terminated */
+typedef void(XMLCALL *XML_ProcessingInstructionHandler)(void *userData,
+ const XML_Char *target,
+ const XML_Char *data);
+
+/* data is 0 terminated */
+typedef void(XMLCALL *XML_CommentHandler)(void *userData, const XML_Char *data);
+
+typedef void(XMLCALL *XML_StartCdataSectionHandler)(void *userData);
+typedef void(XMLCALL *XML_EndCdataSectionHandler)(void *userData);
+
+/* This is called for any characters in the XML document for which
+ there is no applicable handler. This includes both characters that
+ are part of markup which is of a kind that is not reported
+ (comments, markup declarations), or characters that are part of a
+ construct which could be reported but for which no handler has been
+ supplied. The characters are passed exactly as they were in the XML
+ document except that they will be encoded in UTF-8 or UTF-16.
+ Line boundaries are not normalized. Note that a byte order mark
+ character is not passed to the default handler. There are no
+ guarantees about how characters are divided between calls to the
+ default handler: for example, a comment might be split between
+ multiple calls.
+*/
+typedef void(XMLCALL *XML_DefaultHandler)(void *userData, const XML_Char *s,
+ int len);
+
+/* This is called for the start of the DOCTYPE declaration, before
+ any DTD or internal subset is parsed.
+*/
+typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData,
+ const XML_Char *doctypeName,
+ const XML_Char *sysid,
+ const XML_Char *pubid,
+ int has_internal_subset);
+
+/* This is called for the end of the DOCTYPE declaration when the
+ closing > is encountered, but after processing any external
+ subset.
+*/
+typedef void(XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
+
+/* This is called for entity declarations. The is_parameter_entity
+ argument will be non-zero if the entity is a parameter entity, zero
+ otherwise.
+
+ For internal entities (), value will
+ be non-NULL and systemId, publicID, and notationName will be NULL.
+ The value string is NOT null-terminated; the length is provided in
+ the value_length argument. Since it is legal to have zero-length
+ values, do not use this argument to test for internal entities.
+
+ For external entities, value will be NULL and systemId will be
+ non-NULL. The publicId argument will be NULL unless a public
+ identifier was provided. The notationName argument will have a
+ non-NULL value only for unparsed entity declarations.
+
+ Note that is_parameter_entity can't be changed to XML_Bool, since
+ that would break binary compatibility.
+*/
+typedef void(XMLCALL *XML_EntityDeclHandler)(
+ void *userData, const XML_Char *entityName, int is_parameter_entity,
+ const XML_Char *value, int value_length, const XML_Char *base,
+ const XML_Char *systemId, const XML_Char *publicId,
+ const XML_Char *notationName);
+
+XMLPARSEAPI(void)
+XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler);
+
+/* OBSOLETE -- OBSOLETE -- OBSOLETE
+ This handler has been superseded by the EntityDeclHandler above.
+ It is provided here for backward compatibility.
+
+ This is called for a declaration of an unparsed (NDATA) entity.
+ The base argument is whatever was set by XML_SetBase. The
+ entityName, systemId and notationName arguments will never be
+ NULL. The other arguments may be.
+*/
+typedef void(XMLCALL *XML_UnparsedEntityDeclHandler)(
+ void *userData, const XML_Char *entityName, const XML_Char *base,
+ const XML_Char *systemId, const XML_Char *publicId,
+ const XML_Char *notationName);
+
+/* This is called for a declaration of notation. The base argument is
+ whatever was set by XML_SetBase. The notationName will never be
+ NULL. The other arguments can be.
+*/
+typedef void(XMLCALL *XML_NotationDeclHandler)(void *userData,
+ const XML_Char *notationName,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId);
+
+/* When namespace processing is enabled, these are called once for
+ each namespace declaration. The call to the start and end element
+ handlers occur between the calls to the start and end namespace
+ declaration handlers. For an xmlns attribute, prefix will be
+ NULL. For an xmlns="" attribute, uri will be NULL.
+*/
+typedef void(XMLCALL *XML_StartNamespaceDeclHandler)(void *userData,
+ const XML_Char *prefix,
+ const XML_Char *uri);
+
+typedef void(XMLCALL *XML_EndNamespaceDeclHandler)(void *userData,
+ const XML_Char *prefix);
+
+/* This is called if the document is not standalone, that is, it has an
+ external subset or a reference to a parameter entity, but does not
+ have standalone="yes". If this handler returns XML_STATUS_ERROR,
+ then processing will not continue, and the parser will return a
+ XML_ERROR_NOT_STANDALONE error.
+ If parameter entity parsing is enabled, then in addition to the
+ conditions above this handler will only be called if the referenced
+ entity was actually read.
+*/
+typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData);
+
+/* This is called for a reference to an external parsed general
+ entity. The referenced entity is not automatically parsed. The
+ application can parse it immediately or later using
+ XML_ExternalEntityParserCreate.
+
+ The parser argument is the parser parsing the entity containing the
+ reference; it can be passed as the parser argument to
+ XML_ExternalEntityParserCreate. The systemId argument is the
+ system identifier as specified in the entity declaration; it will
+ not be NULL.
+
+ The base argument is the system identifier that should be used as
+ the base for resolving systemId if systemId was relative; this is
+ set by XML_SetBase; it may be NULL.
+
+ The publicId argument is the public identifier as specified in the
+ entity declaration, or NULL if none was specified; the whitespace
+ in the public identifier will have been normalized as required by
+ the XML spec.
+
+ The context argument specifies the parsing context in the format
+ expected by the context argument to XML_ExternalEntityParserCreate;
+ context is valid only until the handler returns, so if the
+ referenced entity is to be parsed later, it must be copied.
+ context is NULL only when the entity is a parameter entity.
+
+ The handler should return XML_STATUS_ERROR if processing should not
+ continue because of a fatal error in the handling of the external
+ entity. In this case the calling parser will return an
+ XML_ERROR_EXTERNAL_ENTITY_HANDLING error.
+
+ Note that unlike other handlers the first argument is the parser,
+ not userData.
+*/
+typedef int(XMLCALL *XML_ExternalEntityRefHandler)(XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId);
+
+/* This is called in two situations:
+ 1) An entity reference is encountered for which no declaration
+ has been read *and* this is not an error.
+ 2) An internal entity reference is read, but not expanded, because
+ XML_SetDefaultHandler has been called.
+ Note: skipped parameter entities in declarations and skipped general
+ entities in attribute values cannot be reported, because
+ the event would be out of sync with the reporting of the
+ declarations or attribute values
+*/
+typedef void(XMLCALL *XML_SkippedEntityHandler)(void *userData,
+ const XML_Char *entityName,
+ int is_parameter_entity);
+
+/* This structure is filled in by the XML_UnknownEncodingHandler to
+ provide information to the parser about encodings that are unknown
+ to the parser.
+
+ The map[b] member gives information about byte sequences whose
+ first byte is b.
+
+ If map[b] is c where c is >= 0, then b by itself encodes the
+ Unicode scalar value c.
+
+ If map[b] is -1, then the byte sequence is malformed.
+
+ If map[b] is -n, where n >= 2, then b is the first byte of an
+ n-byte sequence that encodes a single Unicode scalar value.
+
+ The data member will be passed as the first argument to the convert
+ function.
+
+ The convert function is used to convert multibyte sequences; s will
+ point to a n-byte sequence where map[(unsigned char)*s] == -n. The
+ convert function must return the Unicode scalar value represented
+ by this byte sequence or -1 if the byte sequence is malformed.
+
+ The convert function may be NULL if the encoding is a single-byte
+ encoding, that is if map[b] >= -1 for all bytes b.
+
+ When the parser is finished with the encoding, then if release is
+ not NULL, it will call release passing it the data member; once
+ release has been called, the convert function will not be called
+ again.
+
+ Expat places certain restrictions on the encodings that are supported
+ using this mechanism.
+
+ 1. Every ASCII character that can appear in a well-formed XML document,
+ other than the characters
+
+ $@\^`{}~
+
+ must be represented by a single byte, and that byte must be the
+ same byte that represents that character in ASCII.
+
+ 2. No character may require more than 4 bytes to encode.
+
+ 3. All characters encoded must have Unicode scalar values <=
+ 0xFFFF, (i.e., characters that would be encoded by surrogates in
+ UTF-16 are not allowed). Note that this restriction doesn't
+ apply to the built-in support for UTF-8 and UTF-16.
+
+ 4. No Unicode character may be encoded by more than one distinct
+ sequence of bytes.
+*/
+typedef struct {
+ int map[256];
+ void *data;
+ int(XMLCALL *convert)(void *data, const char *s);
+ void(XMLCALL *release)(void *data);
+} XML_Encoding;
+
+/* This is called for an encoding that is unknown to the parser.
+
+ The encodingHandlerData argument is that which was passed as the
+ second argument to XML_SetUnknownEncodingHandler.
+
+ The name argument gives the name of the encoding as specified in
+ the encoding declaration.
+
+ If the callback can provide information about the encoding, it must
+ fill in the XML_Encoding structure, and return XML_STATUS_OK.
+ Otherwise it must return XML_STATUS_ERROR.
+
+ If info does not describe a suitable encoding, then the parser will
+ return an XML_ERROR_UNKNOWN_ENCODING error.
+*/
+typedef int(XMLCALL *XML_UnknownEncodingHandler)(void *encodingHandlerData,
+ const XML_Char *name,
+ XML_Encoding *info);
+
+XMLPARSEAPI(void)
+XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
+ XML_EndElementHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetCharacterDataHandler(XML_Parser parser,
+ XML_CharacterDataHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+ XML_ProcessingInstructionHandler handler);
+XMLPARSEAPI(void)
+XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetCdataSectionHandler(XML_Parser parser,
+ XML_StartCdataSectionHandler start,
+ XML_EndCdataSectionHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartCdataSectionHandler(XML_Parser parser,
+ XML_StartCdataSectionHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndCdataSectionHandler(XML_Parser parser,
+ XML_EndCdataSectionHandler end);
+
+/* This sets the default handler and also inhibits expansion of
+ internal entities. These entity references will be passed to the
+ default handler, or to the skipped entity handler, if one is set.
+*/
+XMLPARSEAPI(void)
+XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler);
+
+/* This sets the default handler but does not inhibit expansion of
+ internal entities. The entity reference will not be passed to the
+ default handler.
+*/
+XMLPARSEAPI(void)
+XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start,
+ XML_EndDoctypeDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+ XML_StartDoctypeDeclHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+ XML_UnparsedEntityDeclHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+ XML_StartNamespaceDeclHandler start,
+ XML_EndNamespaceDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+ XML_StartNamespaceDeclHandler start);
+
+XMLPARSEAPI(void)
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+ XML_EndNamespaceDeclHandler end);
+
+XMLPARSEAPI(void)
+XML_SetNotStandaloneHandler(XML_Parser parser,
+ XML_NotStandaloneHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+ XML_ExternalEntityRefHandler handler);
+
+/* If a non-NULL value for arg is specified here, then it will be
+ passed as the first argument to the external entity ref handler
+ instead of the parser object.
+*/
+XMLPARSEAPI(void)
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg);
+
+XMLPARSEAPI(void)
+XML_SetSkippedEntityHandler(XML_Parser parser,
+ XML_SkippedEntityHandler handler);
+
+XMLPARSEAPI(void)
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+ XML_UnknownEncodingHandler handler,
+ void *encodingHandlerData);
+
+/* This can be called within a handler for a start element, end
+ element, processing instruction or character data. It causes the
+ corresponding markup to be passed to the default handler.
+*/
+XMLPARSEAPI(void)
+XML_DefaultCurrent(XML_Parser parser);
+
+/* If do_nst is non-zero, and namespace processing is in effect, and
+ a name has a prefix (i.e. an explicit namespace qualifier) then
+ that name is returned as a triplet in a single string separated by
+ the separator character specified when the parser was created: URI
+ + sep + local_name + sep + prefix.
+
+ If do_nst is zero, then namespace information is returned in the
+ default manner (URI + sep + local_name) whether or not the name
+ has a prefix.
+
+ Note: Calling XML_SetReturnNSTriplet after XML_Parse or
+ XML_ParseBuffer has no effect.
+*/
+
+XMLPARSEAPI(void)
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst);
+
+/* This value is passed as the userData argument to callbacks. */
+XMLPARSEAPI(void)
+XML_SetUserData(XML_Parser parser, void *userData);
+
+/* Returns the last value set by XML_SetUserData or NULL. */
+#define XML_GetUserData(parser) (*(void **)(parser))
+
+/* This is equivalent to supplying an encoding argument to
+ XML_ParserCreate. On success XML_SetEncoding returns non-zero,
+ zero otherwise.
+ Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer
+ has no effect and returns XML_STATUS_ERROR.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
+
+/* If this function is called, then the parser will be passed as the
+ first argument to callbacks instead of userData. The userData will
+ still be accessible using XML_GetUserData.
+*/
+XMLPARSEAPI(void)
+XML_UseParserAsHandlerArg(XML_Parser parser);
+
+/* If useDTD == XML_TRUE is passed to this function, then the parser
+ will assume that there is an external subset, even if none is
+ specified in the document. In such a case the parser will call the
+ externalEntityRefHandler with a value of NULL for the systemId
+ argument (the publicId and context arguments will be NULL as well).
+ Note: For the purpose of checking WFC: Entity Declared, passing
+ useDTD == XML_TRUE will make the parser behave as if the document
+ had a DTD with an external subset.
+ Note: If this function is called, then this must be done before
+ the first call to XML_Parse or XML_ParseBuffer, since it will
+ have no effect after that. Returns
+ XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.
+ Note: If the document does not have a DOCTYPE declaration at all,
+ then startDoctypeDeclHandler and endDoctypeDeclHandler will not
+ be called, despite an external subset being parsed.
+ Note: If XML_DTD is not defined when Expat is compiled, returns
+ XML_ERROR_FEATURE_REQUIRES_XML_DTD.
+ Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT.
+*/
+XMLPARSEAPI(enum XML_Error)
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
+
+/* Sets the base to be used for resolving relative URIs in system
+ identifiers in declarations. Resolving relative identifiers is
+ left to the application: this value will be passed through as the
+ base argument to the XML_ExternalEntityRefHandler,
+ XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base
+ argument will be copied. Returns XML_STATUS_ERROR if out of memory,
+ XML_STATUS_OK otherwise.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_SetBase(XML_Parser parser, const XML_Char *base);
+
+XMLPARSEAPI(const XML_Char *)
+XML_GetBase(XML_Parser parser);
+
+/* Returns the number of the attribute/value pairs passed in last call
+ to the XML_StartElementHandler that were specified in the start-tag
+ rather than defaulted. Each attribute/value pair counts as 2; thus
+ this corresponds to an index into the atts array passed to the
+ XML_StartElementHandler. Returns -1 if parser == NULL.
+*/
+XMLPARSEAPI(int)
+XML_GetSpecifiedAttributeCount(XML_Parser parser);
+
+/* Returns the index of the ID attribute passed in the last call to
+ XML_StartElementHandler, or -1 if there is no ID attribute or
+ parser == NULL. Each attribute/value pair counts as 2; thus this
+ corresponds to an index into the atts array passed to the
+ XML_StartElementHandler.
+*/
+XMLPARSEAPI(int)
+XML_GetIdAttributeIndex(XML_Parser parser);
+
+#ifdef XML_ATTR_INFO
+/* Source file byte offsets for the start and end of attribute names and values.
+ The value indices are exclusive of surrounding quotes; thus in a UTF-8 source
+ file an attribute value of "blah" will yield:
+ info->valueEnd - info->valueStart = 4 bytes.
+*/
+typedef struct {
+ XML_Index nameStart; /* Offset to beginning of the attribute name. */
+ XML_Index nameEnd; /* Offset after the attribute name's last byte. */
+ XML_Index valueStart; /* Offset to beginning of the attribute value. */
+ XML_Index valueEnd; /* Offset after the attribute value's last byte. */
+} XML_AttrInfo;
+
+/* Returns an array of XML_AttrInfo structures for the attribute/value pairs
+ passed in last call to the XML_StartElementHandler that were specified
+ in the start-tag rather than defaulted. Each attribute/value pair counts
+ as 1; thus the number of entries in the array is
+ XML_GetSpecifiedAttributeCount(parser) / 2.
+*/
+XMLPARSEAPI(const XML_AttrInfo *)
+XML_GetAttributeInfo(XML_Parser parser);
+#endif
+
+/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
+ detected. The last call to XML_Parse must have isFinal true; len
+ may be zero for this call (or any other).
+
+ Though the return values for these functions has always been
+ described as a Boolean value, the implementation, at least for the
+ 1.95.x series, has always returned exactly one of the XML_Status
+ values.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
+
+XMLPARSEAPI(void *)
+XML_GetBuffer(XML_Parser parser, int len);
+
+XMLPARSEAPI(enum XML_Status)
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
+
+/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return.
+ Must be called from within a call-back handler, except when aborting
+ (resumable = 0) an already suspended parser. Some call-backs may
+ still follow because they would otherwise get lost. Examples:
+ - endElementHandler() for empty elements when stopped in
+ startElementHandler(),
+ - endNameSpaceDeclHandler() when stopped in endElementHandler(),
+ and possibly others.
+
+ Can be called from most handlers, including DTD related call-backs,
+ except when parsing an external parameter entity and resumable != 0.
+ Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise.
+ Possible error codes:
+ - XML_ERROR_SUSPENDED: when suspending an already suspended parser.
+ - XML_ERROR_FINISHED: when the parser has already finished.
+ - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE.
+
+ When resumable != 0 (true) then parsing is suspended, that is,
+ XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED.
+ Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer()
+ return XML_STATUS_ERROR with error code XML_ERROR_ABORTED.
+
+ *Note*:
+ This will be applied to the current parser instance only, that is, if
+ there is a parent parser then it will continue parsing when the
+ externalEntityRefHandler() returns. It is up to the implementation of
+ the externalEntityRefHandler() to call XML_StopParser() on the parent
+ parser (recursively), if one wants to stop parsing altogether.
+
+ When suspended, parsing can be resumed by calling XML_ResumeParser().
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_StopParser(XML_Parser parser, XML_Bool resumable);
+
+/* Resumes parsing after it has been suspended with XML_StopParser().
+ Must not be called from within a handler call-back. Returns same
+ status codes as XML_Parse() or XML_ParseBuffer().
+ Additional error code XML_ERROR_NOT_SUSPENDED possible.
+
+ *Note*:
+ This must be called on the most deeply nested child parser instance
+ first, and on its parent parser only after the child parser has finished,
+ to be applied recursively until the document entity's parser is restarted.
+ That is, the parent parser will not resume by itself and it is up to the
+ application to call XML_ResumeParser() on it at the appropriate moment.
+*/
+XMLPARSEAPI(enum XML_Status)
+XML_ResumeParser(XML_Parser parser);
+
+enum XML_Parsing { XML_INITIALIZED, XML_PARSING, XML_FINISHED, XML_SUSPENDED };
+
+typedef struct {
+ enum XML_Parsing parsing;
+ XML_Bool finalBuffer;
+} XML_ParsingStatus;
+
+/* Returns status of parser with respect to being initialized, parsing,
+ finished, or suspended and processing the final buffer.
+ XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus,
+ XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED
+*/
+XMLPARSEAPI(void)
+XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status);
+
+/* Creates an XML_Parser object that can parse an external general
+ entity; context is a '\0'-terminated string specifying the parse
+ context; encoding is a '\0'-terminated string giving the name of
+ the externally specified encoding, or NULL if there is no
+ externally specified encoding. The context string consists of a
+ sequence of tokens separated by formfeeds (\f); a token consisting
+ of a name specifies that the general entity of the name is open; a
+ token of the form prefix=uri specifies the namespace for a
+ particular prefix; a token of the form =uri specifies the default
+ namespace. This can be called at any point after the first call to
+ an ExternalEntityRefHandler so longer as the parser has not yet
+ been freed. The new parser is completely independent and may
+ safely be used in a separate thread. The handlers and userData are
+ initialized from the parser argument. Returns NULL if out of memory.
+ Otherwise returns a new XML_Parser object.
+*/
+XMLPARSEAPI(XML_Parser)
+XML_ExternalEntityParserCreate(XML_Parser parser, const XML_Char *context,
+ const XML_Char *encoding);
+
+enum XML_ParamEntityParsing {
+ XML_PARAM_ENTITY_PARSING_NEVER,
+ XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
+ XML_PARAM_ENTITY_PARSING_ALWAYS
+};
+
+/* Controls parsing of parameter entities (including the external DTD
+ subset). If parsing of parameter entities is enabled, then
+ references to external parameter entities (including the external
+ DTD subset) will be passed to the handler set with
+ XML_SetExternalEntityRefHandler. The context passed will be 0.
+
+ Unlike external general entities, external parameter entities can
+ only be parsed synchronously. If the external parameter entity is
+ to be parsed, it must be parsed during the call to the external
+ entity ref handler: the complete sequence of
+ XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and
+ XML_ParserFree calls must be made during this call. After
+ XML_ExternalEntityParserCreate has been called to create the parser
+ for the external parameter entity (context must be 0 for this
+ call), it is illegal to make any calls on the old parser until
+ XML_ParserFree has been called on the newly created parser.
+ If the library has been compiled without support for parameter
+ entity parsing (ie without XML_DTD being defined), then
+ XML_SetParamEntityParsing will return 0 if parsing of parameter
+ entities is requested; otherwise it will return non-zero.
+ Note: If XML_SetParamEntityParsing is called after XML_Parse or
+ XML_ParseBuffer, then it has no effect and will always return 0.
+ Note: If parser == NULL, the function will do nothing and return 0.
+*/
+XMLPARSEAPI(int)
+XML_SetParamEntityParsing(XML_Parser parser,
+ enum XML_ParamEntityParsing parsing);
+
+/* Sets the hash salt to use for internal hash calculations.
+ Helps in preventing DoS attacks based on predicting hash
+ function behavior. This must be called before parsing is started.
+ Returns 1 if successful, 0 when called after parsing has started.
+ Note: If parser == NULL, the function will do nothing and return 0.
+*/
+XMLPARSEAPI(int)
+XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt);
+
+/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
+ XML_GetErrorCode returns information about the error.
+*/
+XMLPARSEAPI(enum XML_Error)
+XML_GetErrorCode(XML_Parser parser);
+
+/* These functions return information about the current parse
+ location. They may be called from any callback called to report
+ some parse event; in this case the location is the location of the
+ first of the sequence of characters that generated the event. When
+ called from callbacks generated by declarations in the document
+ prologue, the location identified isn't as neatly defined, but will
+ be within the relevant markup. When called outside of the callback
+ functions, the position indicated will be just past the last parse
+ event (regardless of whether there was an associated callback).
+
+ They may also be called after returning from a call to XML_Parse
+ or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then
+ the location is the location of the character at which the error
+ was detected; otherwise the location is the location of the last
+ parse event, as described above.
+
+ Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber
+ return 0 to indicate an error.
+ Note: XML_GetCurrentByteIndex returns -1 to indicate an error.
+*/
+XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
+XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
+XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);
+
+/* Return the number of bytes in the current event.
+ Returns 0 if the event is in an internal entity.
+*/
+XMLPARSEAPI(int)
+XML_GetCurrentByteCount(XML_Parser parser);
+
+/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets
+ the integer pointed to by offset to the offset within this buffer
+ of the current parse position, and sets the integer pointed to by size
+ to the size of this buffer (the number of input bytes). Otherwise
+ returns a NULL pointer. Also returns a NULL pointer if a parse isn't
+ active.
+
+ NOTE: The character pointer returned should not be used outside
+ the handler that makes the call.
+*/
+XMLPARSEAPI(const char *)
+XML_GetInputContext(XML_Parser parser, int *offset, int *size);
+
+/* For backwards compatibility with previous versions. */
+#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
+#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
+#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
+
+/* Frees the content model passed to the element declaration handler */
+XMLPARSEAPI(void)
+XML_FreeContentModel(XML_Parser parser, XML_Content *model);
+
+/* Exposing the memory handling functions used in Expat */
+XMLPARSEAPI(void *)
+XML_ATTR_MALLOC
+XML_ATTR_ALLOC_SIZE(2)
+XML_MemMalloc(XML_Parser parser, size_t size);
+
+XMLPARSEAPI(void *)
+XML_ATTR_ALLOC_SIZE(3)
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);
+
+XMLPARSEAPI(void)
+XML_MemFree(XML_Parser parser, void *ptr);
+
+/* Frees memory used by the parser. */
+XMLPARSEAPI(void)
+XML_ParserFree(XML_Parser parser);
+
+/* Returns a string describing the error. */
+XMLPARSEAPI(const XML_LChar *)
+XML_ErrorString(enum XML_Error code);
+
+/* Return a string containing the version number of this expat */
+XMLPARSEAPI(const XML_LChar *)
+XML_ExpatVersion(void);
+
+typedef struct {
+ int major;
+ int minor;
+ int micro;
+} XML_Expat_Version;
+
+/* Return an XML_Expat_Version structure containing numeric version
+ number information for this version of expat.
+*/
+XMLPARSEAPI(XML_Expat_Version)
+XML_ExpatVersionInfo(void);
+
+/* Added in Expat 1.95.5. */
+enum XML_FeatureEnum {
+ XML_FEATURE_END = 0,
+ XML_FEATURE_UNICODE,
+ XML_FEATURE_UNICODE_WCHAR_T,
+ XML_FEATURE_DTD,
+ XML_FEATURE_CONTEXT_BYTES,
+ XML_FEATURE_MIN_SIZE,
+ XML_FEATURE_SIZEOF_XML_CHAR,
+ XML_FEATURE_SIZEOF_XML_LCHAR,
+ XML_FEATURE_NS,
+ XML_FEATURE_LARGE_SIZE,
+ XML_FEATURE_ATTR_INFO,
+ /* Added in Expat 2.4.0. */
+ XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
+ XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT
+ /* Additional features must be added to the end of this enum. */
+};
+
+typedef struct {
+ enum XML_FeatureEnum feature;
+ const XML_LChar *name;
+ long int value;
+} XML_Feature;
+
+XMLPARSEAPI(const XML_Feature *)
+XML_GetFeatureList(void);
+
+#ifdef XML_DTD
+/* Added in Expat 2.4.0. */
+XMLPARSEAPI(XML_Bool)
+XML_SetBillionLaughsAttackProtectionMaximumAmplification(
+ XML_Parser parser, float maximumAmplificationFactor);
+
+/* Added in Expat 2.4.0. */
+XMLPARSEAPI(XML_Bool)
+XML_SetBillionLaughsAttackProtectionActivationThreshold(
+ XML_Parser parser, unsigned long long activationThresholdBytes);
+#endif
+
+/* Expat follows the semantic versioning convention.
+ See http://semver.org.
+*/
+#define XML_MAJOR_VERSION 2
+#define XML_MINOR_VERSION 5
+#define XML_MICRO_VERSION 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not Expat_INCLUDED */
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/expat_config.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/expat_config.h
new file mode 100644
index 0000000..9cff981
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/expat_config.h
@@ -0,0 +1,140 @@
+/* expat_config.h. Generated from expat_config.h.in by configure. */
+/* expat_config.h.in. Generated from configure.ac by autoheader. */
+
+#ifndef EXPAT_CONFIG_H
+#define EXPAT_CONFIG_H 1
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* 1234 = LILENDIAN, 4321 = BIGENDIAN */
+#define BYTEORDER 1234
+
+/* Define to 1 if you have the `arc4random' function. */
+/* #undef HAVE_ARC4RANDOM */
+
+/* Define to 1 if you have the `arc4random_buf' function. */
+/* #undef HAVE_ARC4RANDOM_BUF */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_DLFCN_H */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `getpagesize' function. */
+/* #undef HAVE_GETPAGESIZE */
+
+/* Define to 1 if you have the `getrandom' function. */
+/* #undef HAVE_GETRANDOM */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `bsd' library (-lbsd). */
+/* #undef HAVE_LIBBSD */
+
+/* Define to 1 if you have a working `mmap' system call. */
+/* #undef HAVE_MMAP */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have `syscall' and `SYS_getrandom'. */
+/* #undef HAVE_SYSCALL_GETRANDOM */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "expat"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "expat-bugs@libexpat.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "expat"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "expat 2.5.0"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "expat"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.5.0"
+
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+ required in a freestanding environment). This macro is provided for
+ backward compatibility; new code need not use it. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "2.5.0"
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* # undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Define to allow retrieving the byte offsets for attribute names and values.
+ */
+/* #undef XML_ATTR_INFO */
+
+/* Define to specify how much context to retain around the current parse
+ point. */
+#define XML_CONTEXT_BYTES 1024
+
+/* Define to include code reading entropy from `/dev/urandom'. */
+#define XML_DEV_URANDOM 1
+
+/* Define to make parameter entity parsing functionality available. */
+#define XML_DTD 1
+
+/* Define to make XML Namespaces functionality available. */
+#define XML_NS 1
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `long int' if does not define. */
+/* #undef off_t */
+
+/* Define to `unsigned int' if does not define. */
+/* #undef size_t */
+
+#endif // ndef EXPAT_CONFIG_H
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/expat_external.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/expat_external.h
new file mode 100644
index 0000000..8829f77
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/expat_external.h
@@ -0,0 +1,165 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000 Clark Cooper
+ Copyright (c) 2000-2004 Fred L. Drake, Jr.
+ Copyright (c) 2001-2002 Greg Stein
+ Copyright (c) 2002-2006 Karl Waclawek
+ Copyright (c) 2016 Cristian Rodríguez
+ Copyright (c) 2016-2019 Sebastian Pipping
+ Copyright (c) 2017 Rhodri James
+ Copyright (c) 2018 Yury Gribov
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef Expat_External_INCLUDED
+#define Expat_External_INCLUDED 1
+
+/* External API definitions */
+
+/* Expat tries very hard to make the API boundary very specifically
+ defined. There are two macros defined to control this boundary;
+ each of these can be defined before including this header to
+ achieve some different behavior, but doing so it not recommended or
+ tested frequently.
+
+ XMLCALL - The calling convention to use for all calls across the
+ "library boundary." This will default to cdecl, and
+ try really hard to tell the compiler that's what we
+ want.
+
+ XMLIMPORT - Whatever magic is needed to note that a function is
+ to be imported from a dynamically loaded library
+ (.dll, .so, or .sl, depending on your platform).
+
+ The XMLCALL macro was added in Expat 1.95.7. The only one which is
+ expected to be directly useful in client code is XMLCALL.
+
+ Note that on at least some Unix versions, the Expat library must be
+ compiled with the cdecl calling convention as the default since
+ system headers may assume the cdecl convention.
+*/
+#ifndef XMLCALL
+# if defined(_MSC_VER)
+# define XMLCALL __cdecl
+# elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER)
+# define XMLCALL __attribute__((cdecl))
+# else
+/* For any platform which uses this definition and supports more than
+ one calling convention, we need to extend this definition to
+ declare the convention used on that platform, if it's possible to
+ do so.
+
+ If this is the case for your platform, please file a bug report
+ with information on how to identify your platform via the C
+ pre-processor and how to specify the same calling convention as the
+ platform's malloc() implementation.
+*/
+# define XMLCALL
+# endif
+#endif /* not defined XMLCALL */
+
+#if ! defined(XML_STATIC) && ! defined(XMLIMPORT)
+# ifndef XML_BUILDING_EXPAT
+/* using Expat from an application */
+
+# if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) && ! defined(__CYGWIN__)
+# define XMLIMPORT __declspec(dllimport)
+# endif
+
+# endif
+#endif /* not defined XML_STATIC */
+
+#ifndef XML_ENABLE_VISIBILITY
+# define XML_ENABLE_VISIBILITY 0
+#endif
+
+#if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY
+# define XMLIMPORT __attribute__((visibility("default")))
+#endif
+
+/* If we didn't define it above, define it away: */
+#ifndef XMLIMPORT
+# define XMLIMPORT
+#endif
+
+#if defined(__GNUC__) \
+ && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
+# define XML_ATTR_MALLOC __attribute__((__malloc__))
+#else
+# define XML_ATTR_MALLOC
+#endif
+
+#if defined(__GNUC__) \
+ && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+# define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
+#else
+# define XML_ATTR_ALLOC_SIZE(x)
+#endif
+
+#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef XML_UNICODE_WCHAR_T
+# ifndef XML_UNICODE
+# define XML_UNICODE
+# endif
+# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
+# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
+# endif
+#endif
+
+#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
+# ifdef XML_UNICODE_WCHAR_T
+typedef wchar_t XML_Char;
+typedef wchar_t XML_LChar;
+# else
+typedef unsigned short XML_Char;
+typedef char XML_LChar;
+# endif /* XML_UNICODE_WCHAR_T */
+#else /* Information is UTF-8 encoded. */
+typedef char XML_Char;
+typedef char XML_LChar;
+#endif /* XML_UNICODE */
+
+#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
+typedef long long XML_Index;
+typedef unsigned long long XML_Size;
+#else
+typedef long XML_Index;
+typedef unsigned long XML_Size;
+#endif /* XML_LARGE_SIZE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not Expat_External_INCLUDED */
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/ffi.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/ffi.h
new file mode 100644
index 0000000..98ba2c6
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/ffi.h
@@ -0,0 +1,531 @@
+/* -----------------------------------------------------------------*-C-*-
+ libffi 3.4.4
+ - Copyright (c) 2011, 2014, 2019, 2021, 2022 Anthony Green
+ - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the ``Software''), to deal in the Software without
+ restriction, including without limitation the rights to use, copy,
+ modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+ Most of the API is documented in doc/libffi.texi.
+
+ The raw API is designed to bypass some of the argument packing and
+ unpacking on architectures for which it can be avoided. Routines
+ are provided to emulate the raw API if the underlying platform
+ doesn't allow faster implementation.
+
+ More details on the raw API can be found in:
+
+ http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
+
+ and
+
+ http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
+ -------------------------------------------------------------------- */
+
+#ifndef LIBFFI_H
+#define LIBFFI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Specify which architecture libffi is configured for. */
+#ifndef X86_WIN64
+#define X86_WIN64
+#endif
+
+/* ---- System configuration information --------------------------------- */
+
+/* If these change, update src/mips/ffitarget.h. */
+#define FFI_TYPE_VOID 0
+#define FFI_TYPE_INT 1
+#define FFI_TYPE_FLOAT 2
+#define FFI_TYPE_DOUBLE 3
+#if 1
+#define FFI_TYPE_LONGDOUBLE 4
+#else
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#endif
+#define FFI_TYPE_UINT8 5
+#define FFI_TYPE_SINT8 6
+#define FFI_TYPE_UINT16 7
+#define FFI_TYPE_SINT16 8
+#define FFI_TYPE_UINT32 9
+#define FFI_TYPE_SINT32 10
+#define FFI_TYPE_UINT64 11
+#define FFI_TYPE_SINT64 12
+#define FFI_TYPE_STRUCT 13
+#define FFI_TYPE_POINTER 14
+#define FFI_TYPE_COMPLEX 15
+
+/* This should always refer to the last type code (for sanity checks). */
+#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
+
+#include
+
+#ifndef LIBFFI_ASM
+
+#if defined(_MSC_VER) && !defined(__clang__)
+#define __attribute__(X)
+#endif
+
+#include
+#include
+
+/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
+ But we can find it either under the correct ANSI name, or under GNU
+ C's internal name. */
+
+#define FFI_64_BIT_MAX 9223372036854775807
+
+#ifdef LONG_LONG_MAX
+# define FFI_LONG_LONG_MAX LONG_LONG_MAX
+#else
+# ifdef LLONG_MAX
+# define FFI_LONG_LONG_MAX LLONG_MAX
+# ifdef _AIX52 /* or newer has C99 LLONG_MAX */
+# undef FFI_64_BIT_MAX
+# define FFI_64_BIT_MAX 9223372036854775807LL
+# endif /* _AIX52 or newer */
+# else
+# ifdef __GNUC__
+# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
+# endif
+# ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
+# ifndef __PPC64__
+# if defined (__IBMC__) || defined (__IBMCPP__)
+# define FFI_LONG_LONG_MAX LONGLONG_MAX
+# endif
+# endif /* __PPC64__ */
+# undef FFI_64_BIT_MAX
+# define FFI_64_BIT_MAX 9223372036854775807LL
+# endif
+# endif
+#endif
+
+/* The closure code assumes that this works on pointers, i.e. a size_t
+ can hold a pointer. */
+
+typedef struct _ffi_type
+{
+ size_t size;
+ unsigned short alignment;
+ unsigned short type;
+ struct _ffi_type **elements;
+} ffi_type;
+
+/* Need minimal decorations for DLLs to work on Windows. GCC has
+ autoimport and autoexport. Always mark externally visible symbols
+ as dllimport for MSVC clients, even if it means an extra indirection
+ when using the static version of the library.
+ Besides, as a workaround, they can define FFI_BUILDING if they
+ *know* they are going to link with the static library. */
+#if defined _MSC_VER
+# if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
+# define FFI_API __declspec(dllexport)
+# elif !defined FFI_BUILDING /* Importing libffi.DLL */
+# define FFI_API __declspec(dllimport)
+# else /* Building/linking static library */
+# define FFI_API
+# endif
+#else
+# define FFI_API
+#endif
+
+/* The externally visible type declarations also need the MSVC DLL
+ decorations, or they will not be exported from the object file. */
+#if defined LIBFFI_HIDE_BASIC_TYPES
+# define FFI_EXTERN FFI_API
+#else
+# define FFI_EXTERN extern FFI_API
+#endif
+
+#ifndef LIBFFI_HIDE_BASIC_TYPES
+#if SCHAR_MAX == 127
+# define ffi_type_uchar ffi_type_uint8
+# define ffi_type_schar ffi_type_sint8
+#else
+ #error "char size not supported"
+#endif
+
+#if SHRT_MAX == 32767
+# define ffi_type_ushort ffi_type_uint16
+# define ffi_type_sshort ffi_type_sint16
+#elif SHRT_MAX == 2147483647
+# define ffi_type_ushort ffi_type_uint32
+# define ffi_type_sshort ffi_type_sint32
+#else
+ #error "short size not supported"
+#endif
+
+#if INT_MAX == 32767
+# define ffi_type_uint ffi_type_uint16
+# define ffi_type_sint ffi_type_sint16
+#elif INT_MAX == 2147483647
+# define ffi_type_uint ffi_type_uint32
+# define ffi_type_sint ffi_type_sint32
+#elif INT_MAX == 9223372036854775807
+# define ffi_type_uint ffi_type_uint64
+# define ffi_type_sint ffi_type_sint64
+#else
+ #error "int size not supported"
+#endif
+
+#if LONG_MAX == 2147483647
+# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
+ #error "no 64-bit data type supported"
+# endif
+#elif LONG_MAX != FFI_64_BIT_MAX
+ #error "long size not supported"
+#endif
+
+#if LONG_MAX == 2147483647
+# define ffi_type_ulong ffi_type_uint32
+# define ffi_type_slong ffi_type_sint32
+#elif LONG_MAX == FFI_64_BIT_MAX
+# define ffi_type_ulong ffi_type_uint64
+# define ffi_type_slong ffi_type_sint64
+#else
+ #error "long size not supported"
+#endif
+
+/* These are defined in types.c. */
+FFI_EXTERN ffi_type ffi_type_void;
+FFI_EXTERN ffi_type ffi_type_uint8;
+FFI_EXTERN ffi_type ffi_type_sint8;
+FFI_EXTERN ffi_type ffi_type_uint16;
+FFI_EXTERN ffi_type ffi_type_sint16;
+FFI_EXTERN ffi_type ffi_type_uint32;
+FFI_EXTERN ffi_type ffi_type_sint32;
+FFI_EXTERN ffi_type ffi_type_uint64;
+FFI_EXTERN ffi_type ffi_type_sint64;
+FFI_EXTERN ffi_type ffi_type_float;
+FFI_EXTERN ffi_type ffi_type_double;
+FFI_EXTERN ffi_type ffi_type_pointer;
+
+#if 1
+FFI_EXTERN ffi_type ffi_type_longdouble;
+#else
+#define ffi_type_longdouble ffi_type_double
+#endif
+
+#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
+FFI_EXTERN ffi_type ffi_type_complex_float;
+FFI_EXTERN ffi_type ffi_type_complex_double;
+#if 1
+FFI_EXTERN ffi_type ffi_type_complex_longdouble;
+#else
+#define ffi_type_complex_longdouble ffi_type_complex_double
+#endif
+#endif
+#endif /* LIBFFI_HIDE_BASIC_TYPES */
+
+typedef enum {
+ FFI_OK = 0,
+ FFI_BAD_TYPEDEF,
+ FFI_BAD_ABI,
+ FFI_BAD_ARGTYPE
+} ffi_status;
+
+typedef struct {
+ ffi_abi abi;
+ unsigned nargs;
+ ffi_type **arg_types;
+ ffi_type *rtype;
+ unsigned bytes;
+ unsigned flags;
+#ifdef FFI_EXTRA_CIF_FIELDS
+ FFI_EXTRA_CIF_FIELDS;
+#endif
+} ffi_cif;
+
+/* ---- Definitions for the raw API -------------------------------------- */
+
+#ifndef FFI_SIZEOF_ARG
+# if LONG_MAX == 2147483647
+# define FFI_SIZEOF_ARG 4
+# elif LONG_MAX == FFI_64_BIT_MAX
+# define FFI_SIZEOF_ARG 8
+# endif
+#endif
+
+#ifndef FFI_SIZEOF_JAVA_RAW
+# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
+#endif
+
+typedef union {
+ ffi_sarg sint;
+ ffi_arg uint;
+ float flt;
+ char data[FFI_SIZEOF_ARG];
+ void* ptr;
+} ffi_raw;
+
+#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
+/* This is a special case for mips64/n32 ABI (and perhaps others) where
+ sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
+typedef union {
+ signed int sint;
+ unsigned int uint;
+ float flt;
+ char data[FFI_SIZEOF_JAVA_RAW];
+ void* ptr;
+} ffi_java_raw;
+#else
+typedef ffi_raw ffi_java_raw;
+#endif
+
+
+FFI_API
+void ffi_raw_call (ffi_cif *cif,
+ void (*fn)(void),
+ void *rvalue,
+ ffi_raw *avalue);
+
+FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+FFI_API size_t ffi_raw_size (ffi_cif *cif);
+
+/* This is analogous to the raw API, except it uses Java parameter
+ packing, even on 64-bit machines. I.e. on 64-bit machines longs
+ and doubles are followed by an empty 64-bit word. */
+
+#if !FFI_NATIVE_RAW_API
+FFI_API
+void ffi_java_raw_call (ffi_cif *cif,
+ void (*fn)(void),
+ void *rvalue,
+ ffi_java_raw *avalue) __attribute__((deprecated));
+#endif
+
+FFI_API
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) __attribute__((deprecated));
+FFI_API
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) __attribute__((deprecated));
+FFI_API
+size_t ffi_java_raw_size (ffi_cif *cif) __attribute__((deprecated));
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if FFI_CLOSURES
+
+#ifdef _MSC_VER
+__declspec(align(8))
+#endif
+typedef struct {
+#if 0
+ void *trampoline_table;
+ void *trampoline_table_entry;
+#else
+ union {
+ char tramp[FFI_TRAMPOLINE_SIZE];
+ void *ftramp;
+ };
+#endif
+ ffi_cif *cif;
+ void (*fun)(ffi_cif*,void*,void**,void*);
+ void *user_data;
+#if defined(_MSC_VER) && defined(_M_IX86)
+ void *padding;
+#endif
+} ffi_closure
+#ifdef __GNUC__
+ __attribute__((aligned (8)))
+#endif
+ ;
+
+#ifndef __GNUC__
+# ifdef __sgi
+# pragma pack 0
+# endif
+#endif
+
+FFI_API void *ffi_closure_alloc (size_t size, void **code);
+FFI_API void ffi_closure_free (void *);
+
+#if defined(PA_LINUX) || defined(PA_HPUX)
+#define FFI_CLOSURE_PTR(X) ((void *)((unsigned int)(X) | 2))
+#define FFI_RESTORE_PTR(X) ((void *)((unsigned int)(X) & ~3))
+#else
+#define FFI_CLOSURE_PTR(X) (X)
+#define FFI_RESTORE_PTR(X) (X)
+#endif
+
+FFI_API ffi_status
+ffi_prep_closure (ffi_closure*,
+ ffi_cif *,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data)
+#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
+ __attribute__((deprecated ("use ffi_prep_closure_loc instead")))
+#elif defined(__GNUC__) && __GNUC__ >= 3
+ __attribute__((deprecated))
+#endif
+ ;
+
+FFI_API ffi_status
+ffi_prep_closure_loc (ffi_closure*,
+ ffi_cif *,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data,
+ void *codeloc);
+
+#ifdef __sgi
+# pragma pack 8
+#endif
+typedef struct {
+#if 0
+ void *trampoline_table;
+ void *trampoline_table_entry;
+#else
+ char tramp[FFI_TRAMPOLINE_SIZE];
+#endif
+ ffi_cif *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+ /* If this is enabled, then a raw closure has the same layout
+ as a regular closure. We use this to install an intermediate
+ handler to do the translation, void** -> ffi_raw*. */
+
+ void (*translate_args)(ffi_cif*,void*,void**,void*);
+ void *this_closure;
+
+#endif
+
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+ void *user_data;
+
+} ffi_raw_closure;
+
+typedef struct {
+#if 0
+ void *trampoline_table;
+ void *trampoline_table_entry;
+#else
+ char tramp[FFI_TRAMPOLINE_SIZE];
+#endif
+
+ ffi_cif *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+ /* If this is enabled, then a raw closure has the same layout
+ as a regular closure. We use this to install an intermediate
+ handler to do the translation, void** -> ffi_raw*. */
+
+ void (*translate_args)(ffi_cif*,void*,void**,void*);
+ void *this_closure;
+
+#endif
+
+ void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
+ void *user_data;
+
+} ffi_java_raw_closure;
+
+FFI_API ffi_status
+ffi_prep_raw_closure (ffi_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data);
+
+FFI_API ffi_status
+ffi_prep_raw_closure_loc (ffi_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data,
+ void *codeloc);
+
+#if !FFI_NATIVE_RAW_API
+FFI_API ffi_status
+ffi_prep_java_raw_closure (ffi_java_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
+ void *user_data) __attribute__((deprecated));
+
+FFI_API ffi_status
+ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
+ void *user_data,
+ void *codeloc) __attribute__((deprecated));
+#endif
+
+#endif /* FFI_CLOSURES */
+
+#if FFI_GO_CLOSURES
+
+typedef struct {
+ void *tramp;
+ ffi_cif *cif;
+ void (*fun)(ffi_cif*,void*,void**,void*);
+} ffi_go_closure;
+
+FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
+ void (*fun)(ffi_cif*,void*,void**,void*));
+
+FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
+ void **avalue, void *closure);
+
+#endif /* FFI_GO_CLOSURES */
+
+/* ---- Public interface definition -------------------------------------- */
+
+FFI_API
+ffi_status ffi_prep_cif(ffi_cif *cif,
+ ffi_abi abi,
+ unsigned int nargs,
+ ffi_type *rtype,
+ ffi_type **atypes);
+
+FFI_API
+ffi_status ffi_prep_cif_var(ffi_cif *cif,
+ ffi_abi abi,
+ unsigned int nfixedargs,
+ unsigned int ntotalargs,
+ ffi_type *rtype,
+ ffi_type **atypes);
+
+FFI_API
+void ffi_call(ffi_cif *cif,
+ void (*fn)(void),
+ void *rvalue,
+ void **avalue);
+
+FFI_API
+ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
+ size_t *offsets);
+
+/* Useful for eliminating compiler warnings. */
+#define FFI_FN(f) ((void (*)(void))f)
+
+/* ---- Definitions shared with assembly code ---------------------------- */
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/ffitarget.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/ffitarget.h
new file mode 100644
index 0000000..5a3399d
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/ffitarget.h
@@ -0,0 +1,164 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
+ Copyright (c) 1996-2003, 2010 Red Hat, Inc.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+
+ Target configuration macros for x86 and x86-64.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
+ ----------------------------------------------------------------------- */
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_H
+#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
+#endif
+
+/* ---- System specific configurations ----------------------------------- */
+
+/* For code common to all platforms on x86 and x86_64. */
+#define X86_ANY
+
+#if defined (X86_64) && defined (__i386__)
+#undef X86_64
+#warning ******************************************************
+#warning ********** X86 IS DEFINED ****************************
+#warning ******************************************************
+#define X86
+#endif
+
+#ifdef X86_WIN64
+#define FFI_SIZEOF_ARG 8
+#define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
+#endif
+
+#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
+#ifndef _MSC_VER
+#define FFI_TARGET_HAS_COMPLEX_TYPE
+#endif
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#ifndef LIBFFI_ASM
+#ifdef X86_WIN64
+#ifdef _MSC_VER
+typedef unsigned __int64 ffi_arg;
+typedef __int64 ffi_sarg;
+#else
+typedef unsigned long long ffi_arg;
+typedef long long ffi_sarg;
+#endif
+#else
+#if defined __x86_64__ && defined __ILP32__
+#define FFI_SIZEOF_ARG 8
+#define FFI_SIZEOF_JAVA_RAW 4
+typedef unsigned long long ffi_arg;
+typedef long long ffi_sarg;
+#else
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+#endif
+#endif
+
+typedef enum ffi_abi {
+#if defined(X86_WIN64)
+ FFI_FIRST_ABI = 0,
+ FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
+ FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
+ FFI_LAST_ABI,
+#ifdef __GNUC__
+ FFI_DEFAULT_ABI = FFI_GNUW64
+#else
+ FFI_DEFAULT_ABI = FFI_WIN64
+#endif
+
+#elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
+ FFI_FIRST_ABI = 1,
+ FFI_UNIX64,
+ FFI_WIN64,
+ FFI_EFI64 = FFI_WIN64,
+ FFI_GNUW64,
+ FFI_LAST_ABI,
+ FFI_DEFAULT_ABI = FFI_UNIX64
+
+#elif defined(X86_WIN32)
+ FFI_FIRST_ABI = 0,
+ FFI_SYSV = 1,
+ FFI_STDCALL = 2,
+ FFI_THISCALL = 3,
+ FFI_FASTCALL = 4,
+ FFI_MS_CDECL = 5,
+ FFI_PASCAL = 6,
+ FFI_REGISTER = 7,
+ FFI_LAST_ABI,
+ FFI_DEFAULT_ABI = FFI_MS_CDECL
+#else
+ FFI_FIRST_ABI = 0,
+ FFI_SYSV = 1,
+ FFI_THISCALL = 3,
+ FFI_FASTCALL = 4,
+ FFI_STDCALL = 5,
+ FFI_PASCAL = 6,
+ FFI_REGISTER = 7,
+ FFI_MS_CDECL = 8,
+ FFI_LAST_ABI,
+ FFI_DEFAULT_ABI = FFI_SYSV
+#endif
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_GO_CLOSURES 1
+
+#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
+#define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
+#define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
+#define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
+
+#if defined (X86_64) || defined(X86_WIN64) \
+ || (defined (__x86_64__) && defined (X86_DARWIN))
+/* 4 bytes of ENDBR64 + 7 bytes of LEA + 6 bytes of JMP + 7 bytes of NOP
+ + 8 bytes of pointer. */
+# define FFI_TRAMPOLINE_SIZE 32
+# define FFI_NATIVE_RAW_API 0
+#else
+/* 4 bytes of ENDBR32 + 5 bytes of MOV + 5 bytes of JMP + 2 unused
+ bytes. */
+# define FFI_TRAMPOLINE_SIZE 16
+# define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
+#endif
+
+#if !defined(GENERATE_LIBFFI_MAP) && defined(__CET__)
+# include
+# if (__CET__ & 1) != 0
+# define ENDBR_PRESENT
+# endif
+# define _CET_NOTRACK notrack
+#else
+# define _CET_ENDBR
+# define _CET_NOTRACK
+#endif
+
+#endif
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/fontconfig/fcfreetype.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/fontconfig/fcfreetype.h
new file mode 100644
index 0000000..20b1128
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/fontconfig/fcfreetype.h
@@ -0,0 +1,59 @@
+/*
+ * fontconfig/fontconfig/fcfreetype.h
+ *
+ * Copyright © 2001 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _FCFREETYPE_H_
+#define _FCFREETYPE_H_
+#include
+#include FT_FREETYPE_H
+
+#ifndef FcPublic
+#define FcPublic
+#endif
+
+_FCFUNCPROTOBEGIN
+
+FcPublic FT_UInt
+FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4);
+
+FcPublic FcCharSet *
+FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing);
+
+FcPublic FcCharSet *
+FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks);
+
+FcPublic FcResult
+FcPatternGetFTFace (const FcPattern *p, const char *object, int n, FT_Face *f);
+
+FcPublic FcBool
+FcPatternAddFTFace (FcPattern *p, const char *object, const FT_Face f);
+
+FcPublic FcPattern *
+FcFreeTypeQueryFace (const FT_Face face,
+ const FcChar8 *file,
+ unsigned int id,
+ FcBlanks *blanks);
+
+_FCFUNCPROTOEND
+
+#endif
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/fontconfig/fcprivate.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/fontconfig/fcprivate.h
new file mode 100644
index 0000000..23021b2
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/fontconfig/fcprivate.h
@@ -0,0 +1,134 @@
+/*
+ * fontconfig/fontconfig/fcprivate.h
+ *
+ * Copyright © 2001 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _FCPRIVATE_H_
+#define _FCPRIVATE_H_
+
+/*
+ * I tried this with functions that took va_list* arguments
+ * but portability concerns made me change these functions
+ * into macros (sigh).
+ */
+
+#define FcPatternVapBuild(result, orig, va) \
+{ \
+ FcPattern *__p__ = (orig); \
+ const char *__o__; \
+ FcValue __v__; \
+ \
+ if (!__p__) \
+ { \
+ __p__ = FcPatternCreate (); \
+ if (!__p__) \
+ goto _FcPatternVapBuild_bail0; \
+ } \
+ for (;;) \
+ { \
+ __o__ = va_arg (va, const char *); \
+ if (!__o__) \
+ break; \
+ __v__.type = va_arg (va, int); \
+ switch (__v__.type) { \
+ case FcTypeUnknown: \
+ case FcTypeVoid: \
+ goto _FcPatternVapBuild_bail1; \
+ case FcTypeInteger: \
+ __v__.u.i = va_arg (va, int); \
+ break; \
+ case FcTypeDouble: \
+ __v__.u.d = va_arg (va, double); \
+ break; \
+ case FcTypeString: \
+ __v__.u.s = va_arg (va, const FcChar8 *); \
+ break; \
+ case FcTypeBool: \
+ __v__.u.b = va_arg (va, FcBool); \
+ break; \
+ case FcTypeMatrix: \
+ __v__.u.m = va_arg (va, const FcMatrix *); \
+ break; \
+ case FcTypeCharSet: \
+ __v__.u.c = va_arg (va, const FcCharSet *); \
+ break; \
+ case FcTypeFTFace: \
+ __v__.u.f = va_arg (va, FT_Face); \
+ break; \
+ case FcTypeLangSet: \
+ __v__.u.l = va_arg (va, const FcLangSet *); \
+ break; \
+ case FcTypeRange: \
+ __v__.u.r = va_arg (va, const FcRange *); \
+ break; \
+ } \
+ if (!FcPatternAdd (__p__, __o__, __v__, FcTrue)) \
+ goto _FcPatternVapBuild_bail1; \
+ } \
+ result = __p__; \
+ goto _FcPatternVapBuild_return; \
+ \
+_FcPatternVapBuild_bail1: \
+ if (!orig) \
+ FcPatternDestroy (__p__); \
+_FcPatternVapBuild_bail0: \
+ result = (void*)0; \
+ \
+_FcPatternVapBuild_return: \
+ ; \
+}
+
+
+#define FcObjectSetVapBuild(__ret__, __first__, __va__) \
+{ \
+ FcObjectSet *__os__; \
+ const char *__ob__; \
+ \
+ __ret__ = 0; \
+ __os__ = FcObjectSetCreate (); \
+ if (!__os__) \
+ goto _FcObjectSetVapBuild_bail0; \
+ __ob__ = __first__; \
+ while (__ob__) \
+ { \
+ if (!FcObjectSetAdd (__os__, __ob__)) \
+ goto _FcObjectSetVapBuild_bail1; \
+ __ob__ = va_arg (__va__, const char *); \
+ } \
+ __ret__ = __os__; \
+ \
+_FcObjectSetVapBuild_bail1: \
+ if (!__ret__ && __os__) \
+ FcObjectSetDestroy (__os__); \
+_FcObjectSetVapBuild_bail0: \
+ ; \
+}
+
+#ifndef FC_ATTRIBUTE_VISIBILITY_HIDDEN
+#define FC_ATTRIBUTE_VISIBILITY_HIDDEN __attribute((visibility("hidden")))
+#endif
+
+#ifndef FC_ATTRIBUTE_VISIBILITY_EXPORT
+#define FC_ATTRIBUTE_VISIBILITY_EXPORT __attribute((visibility("default")))
+#endif
+
+#endif /* _FCPRIVATE_H_ */
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/fontconfig/fontconfig.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/fontconfig/fontconfig.h
new file mode 100644
index 0000000..09292a3
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/fontconfig/fontconfig.h
@@ -0,0 +1,1154 @@
+/*
+ * fontconfig/fontconfig/fontconfig.h
+ *
+ * Copyright © 2001 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _FONTCONFIG_H_
+#define _FONTCONFIG_H_
+
+#include
+#include
+#include
+#include
+
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#define FC_ATTRIBUTE_SENTINEL(x) __attribute__((__sentinel__(0)))
+#else
+#define FC_ATTRIBUTE_SENTINEL(x)
+#endif
+
+#ifndef FcPublic
+#define FcPublic
+#endif
+
+typedef unsigned char FcChar8;
+typedef unsigned short FcChar16;
+typedef unsigned int FcChar32;
+typedef int FcBool;
+
+/*
+ * Current Fontconfig version number. This same number
+ * must appear in the fontconfig configure.in file. Yes,
+ * it'a a pain to synchronize version numbers like this.
+ */
+
+#define FC_MAJOR 2
+#define FC_MINOR 14
+#define FC_REVISION 1
+
+#define FC_VERSION ((FC_MAJOR * 10000) + (FC_MINOR * 100) + (FC_REVISION))
+
+/*
+ * Current font cache file format version
+ * This is appended to the cache files so that multiple
+ * versions of the library will peacefully coexist
+ *
+ * Change this value whenever the disk format for the cache file
+ * changes in any non-compatible way. Try to avoid such changes as
+ * it means multiple copies of the font information.
+ */
+
+#define FC_CACHE_VERSION_NUMBER 8
+#define _FC_STRINGIFY_(s) #s
+#define _FC_STRINGIFY(s) _FC_STRINGIFY_(s)
+#define FC_CACHE_VERSION _FC_STRINGIFY(FC_CACHE_VERSION_NUMBER)
+
+#define FcFalse 0
+#define FcTrue 1
+#define FcDontCare 2
+
+#define FC_FAMILY "family" /* String */
+#define FC_STYLE "style" /* String */
+#define FC_SLANT "slant" /* Int */
+#define FC_WEIGHT "weight" /* Int */
+#define FC_SIZE "size" /* Range (double) */
+#define FC_ASPECT "aspect" /* Double */
+#define FC_PIXEL_SIZE "pixelsize" /* Double */
+#define FC_SPACING "spacing" /* Int */
+#define FC_FOUNDRY "foundry" /* String */
+#define FC_ANTIALIAS "antialias" /* Bool (depends) */
+#define FC_HINTING "hinting" /* Bool (true) */
+#define FC_HINT_STYLE "hintstyle" /* Int */
+#define FC_VERTICAL_LAYOUT "verticallayout" /* Bool (false) */
+#define FC_AUTOHINT "autohint" /* Bool (false) */
+/* FC_GLOBAL_ADVANCE is deprecated. this is simply ignored on freetype 2.4.5 or later */
+#define FC_GLOBAL_ADVANCE "globaladvance" /* Bool (true) */
+#define FC_WIDTH "width" /* Int */
+#define FC_FILE "file" /* String */
+#define FC_INDEX "index" /* Int */
+#define FC_FT_FACE "ftface" /* FT_Face */
+#define FC_RASTERIZER "rasterizer" /* String (deprecated) */
+#define FC_OUTLINE "outline" /* Bool */
+#define FC_SCALABLE "scalable" /* Bool */
+#define FC_COLOR "color" /* Bool */
+#define FC_VARIABLE "variable" /* Bool */
+#define FC_SCALE "scale" /* double (deprecated) */
+#define FC_SYMBOL "symbol" /* Bool */
+#define FC_DPI "dpi" /* double */
+#define FC_RGBA "rgba" /* Int */
+#define FC_MINSPACE "minspace" /* Bool use minimum line spacing */
+#define FC_SOURCE "source" /* String (deprecated) */
+#define FC_CHARSET "charset" /* CharSet */
+#define FC_LANG "lang" /* LangSet Set of RFC 3066 langs */
+#define FC_FONTVERSION "fontversion" /* Int from 'head' table */
+#define FC_FULLNAME "fullname" /* String */
+#define FC_FAMILYLANG "familylang" /* String RFC 3066 langs */
+#define FC_STYLELANG "stylelang" /* String RFC 3066 langs */
+#define FC_FULLNAMELANG "fullnamelang" /* String RFC 3066 langs */
+#define FC_CAPABILITY "capability" /* String */
+#define FC_FONTFORMAT "fontformat" /* String */
+#define FC_EMBOLDEN "embolden" /* Bool - true if emboldening needed*/
+#define FC_EMBEDDED_BITMAP "embeddedbitmap" /* Bool - true to enable embedded bitmaps */
+#define FC_DECORATIVE "decorative" /* Bool - true if style is a decorative variant */
+#define FC_LCD_FILTER "lcdfilter" /* Int */
+#define FC_FONT_FEATURES "fontfeatures" /* String */
+#define FC_FONT_VARIATIONS "fontvariations" /* String */
+#define FC_NAMELANG "namelang" /* String RFC 3866 langs */
+#define FC_PRGNAME "prgname" /* String */
+#define FC_HASH "hash" /* String (deprecated) */
+#define FC_POSTSCRIPT_NAME "postscriptname" /* String */
+#define FC_FONT_HAS_HINT "fonthashint" /* Bool - true if font has hinting */
+#define FC_ORDER "order" /* Integer */
+
+#define FC_CACHE_SUFFIX ".cache-" FC_CACHE_VERSION
+#define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION
+#define FC_USER_CACHE_FILE ".fonts.cache-" FC_CACHE_VERSION
+
+/* Adjust outline rasterizer */
+#define FC_CHARWIDTH "charwidth" /* Int */
+#define FC_CHAR_WIDTH FC_CHARWIDTH
+#define FC_CHAR_HEIGHT "charheight"/* Int */
+#define FC_MATRIX "matrix" /* FcMatrix */
+
+#define FC_WEIGHT_THIN 0
+#define FC_WEIGHT_EXTRALIGHT 40
+#define FC_WEIGHT_ULTRALIGHT FC_WEIGHT_EXTRALIGHT
+#define FC_WEIGHT_LIGHT 50
+#define FC_WEIGHT_DEMILIGHT 55
+#define FC_WEIGHT_SEMILIGHT FC_WEIGHT_DEMILIGHT
+#define FC_WEIGHT_BOOK 75
+#define FC_WEIGHT_REGULAR 80
+#define FC_WEIGHT_NORMAL FC_WEIGHT_REGULAR
+#define FC_WEIGHT_MEDIUM 100
+#define FC_WEIGHT_DEMIBOLD 180
+#define FC_WEIGHT_SEMIBOLD FC_WEIGHT_DEMIBOLD
+#define FC_WEIGHT_BOLD 200
+#define FC_WEIGHT_EXTRABOLD 205
+#define FC_WEIGHT_ULTRABOLD FC_WEIGHT_EXTRABOLD
+#define FC_WEIGHT_BLACK 210
+#define FC_WEIGHT_HEAVY FC_WEIGHT_BLACK
+#define FC_WEIGHT_EXTRABLACK 215
+#define FC_WEIGHT_ULTRABLACK FC_WEIGHT_EXTRABLACK
+
+#define FC_SLANT_ROMAN 0
+#define FC_SLANT_ITALIC 100
+#define FC_SLANT_OBLIQUE 110
+
+#define FC_WIDTH_ULTRACONDENSED 50
+#define FC_WIDTH_EXTRACONDENSED 63
+#define FC_WIDTH_CONDENSED 75
+#define FC_WIDTH_SEMICONDENSED 87
+#define FC_WIDTH_NORMAL 100
+#define FC_WIDTH_SEMIEXPANDED 113
+#define FC_WIDTH_EXPANDED 125
+#define FC_WIDTH_EXTRAEXPANDED 150
+#define FC_WIDTH_ULTRAEXPANDED 200
+
+#define FC_PROPORTIONAL 0
+#define FC_DUAL 90
+#define FC_MONO 100
+#define FC_CHARCELL 110
+
+/* sub-pixel order */
+#define FC_RGBA_UNKNOWN 0
+#define FC_RGBA_RGB 1
+#define FC_RGBA_BGR 2
+#define FC_RGBA_VRGB 3
+#define FC_RGBA_VBGR 4
+#define FC_RGBA_NONE 5
+
+/* hinting style */
+#define FC_HINT_NONE 0
+#define FC_HINT_SLIGHT 1
+#define FC_HINT_MEDIUM 2
+#define FC_HINT_FULL 3
+
+/* LCD filter */
+#define FC_LCD_NONE 0
+#define FC_LCD_DEFAULT 1
+#define FC_LCD_LIGHT 2
+#define FC_LCD_LEGACY 3
+
+typedef enum _FcType {
+ FcTypeUnknown = -1,
+ FcTypeVoid,
+ FcTypeInteger,
+ FcTypeDouble,
+ FcTypeString,
+ FcTypeBool,
+ FcTypeMatrix,
+ FcTypeCharSet,
+ FcTypeFTFace,
+ FcTypeLangSet,
+ FcTypeRange
+} FcType;
+
+typedef struct _FcMatrix {
+ double xx, xy, yx, yy;
+} FcMatrix;
+
+#define FcMatrixInit(m) ((m)->xx = (m)->yy = 1, \
+ (m)->xy = (m)->yx = 0)
+
+/*
+ * A data structure to represent the available glyphs in a font.
+ * This is represented as a sparse boolean btree.
+ */
+
+typedef struct _FcCharSet FcCharSet;
+
+typedef struct _FcObjectType {
+ char *object;
+ FcType type;
+} FcObjectType;
+
+typedef struct _FcConstant {
+ const FcChar8 *name;
+ const char *object;
+ int value;
+} FcConstant;
+
+typedef enum _FcResult {
+ FcResultMatch, FcResultNoMatch, FcResultTypeMismatch, FcResultNoId,
+ FcResultOutOfMemory
+} FcResult;
+
+typedef enum _FcValueBinding {
+ FcValueBindingWeak, FcValueBindingStrong, FcValueBindingSame,
+ /* to make sure sizeof (FcValueBinding) == 4 even with -fshort-enums */
+ FcValueBindingEnd = INT_MAX
+} FcValueBinding;
+
+typedef struct _FcPattern FcPattern;
+
+typedef struct _FcPatternIter {
+ void *dummy1;
+ void *dummy2;
+} FcPatternIter;
+
+typedef struct _FcLangSet FcLangSet;
+
+typedef struct _FcRange FcRange;
+
+typedef struct _FcValue {
+ FcType type;
+ union {
+ const FcChar8 *s;
+ int i;
+ FcBool b;
+ double d;
+ const FcMatrix *m;
+ const FcCharSet *c;
+ void *f;
+ const FcLangSet *l;
+ const FcRange *r;
+ } u;
+} FcValue;
+
+typedef struct _FcFontSet {
+ int nfont;
+ int sfont;
+ FcPattern **fonts;
+} FcFontSet;
+
+typedef struct _FcObjectSet {
+ int nobject;
+ int sobject;
+ const char **objects;
+} FcObjectSet;
+
+typedef enum _FcMatchKind {
+ FcMatchPattern, FcMatchFont, FcMatchScan,
+ FcMatchKindEnd,
+ FcMatchKindBegin = FcMatchPattern
+} FcMatchKind;
+
+typedef enum _FcLangResult {
+ FcLangEqual = 0,
+ FcLangDifferentCountry = 1,
+ FcLangDifferentTerritory = 1,
+ FcLangDifferentLang = 2
+} FcLangResult;
+
+typedef enum _FcSetName {
+ FcSetSystem = 0,
+ FcSetApplication = 1
+} FcSetName;
+
+typedef struct _FcConfigFileInfoIter {
+ void *dummy1;
+ void *dummy2;
+ void *dummy3;
+} FcConfigFileInfoIter;
+
+typedef struct _FcAtomic FcAtomic;
+
+#if defined(__cplusplus) || defined(c_plusplus) /* for C++ V2.0 */
+#define _FCFUNCPROTOBEGIN extern "C" { /* do not leave open across includes */
+#define _FCFUNCPROTOEND }
+#else
+#define _FCFUNCPROTOBEGIN
+#define _FCFUNCPROTOEND
+#endif
+
+typedef enum { FcEndianBig, FcEndianLittle } FcEndian;
+
+typedef struct _FcConfig FcConfig;
+
+typedef struct _FcGlobalCache FcFileCache;
+
+typedef struct _FcBlanks FcBlanks;
+
+typedef struct _FcStrList FcStrList;
+
+typedef struct _FcStrSet FcStrSet;
+
+typedef struct _FcCache FcCache;
+
+_FCFUNCPROTOBEGIN
+
+/* fcblanks.c */
+FcPublic FcBlanks *
+FcBlanksCreate (void);
+
+FcPublic void
+FcBlanksDestroy (FcBlanks *b);
+
+FcPublic FcBool
+FcBlanksAdd (FcBlanks *b, FcChar32 ucs4);
+
+FcPublic FcBool
+FcBlanksIsMember (FcBlanks *b, FcChar32 ucs4);
+
+/* fccache.c */
+
+FcPublic const FcChar8 *
+FcCacheDir(const FcCache *c);
+
+FcPublic FcFontSet *
+FcCacheCopySet(const FcCache *c);
+
+FcPublic const FcChar8 *
+FcCacheSubdir (const FcCache *c, int i);
+
+FcPublic int
+FcCacheNumSubdir (const FcCache *c);
+
+FcPublic int
+FcCacheNumFont (const FcCache *c);
+
+FcPublic FcBool
+FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config);
+
+FcPublic FcBool
+FcDirCacheValid (const FcChar8 *cache_file);
+
+FcPublic FcBool
+FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose);
+
+FcPublic void
+FcCacheCreateTagFile (FcConfig *config);
+
+FcPublic FcBool
+FcDirCacheCreateUUID (FcChar8 *dir,
+ FcBool force,
+ FcConfig *config);
+
+FcPublic FcBool
+FcDirCacheDeleteUUID (const FcChar8 *dir,
+ FcConfig *config);
+
+/* fccfg.c */
+FcPublic FcChar8 *
+FcConfigHome (void);
+
+FcPublic FcBool
+FcConfigEnableHome (FcBool enable);
+
+FcPublic FcChar8 *
+FcConfigGetFilename (FcConfig *config,
+ const FcChar8 *url);
+
+FcPublic FcChar8 *
+FcConfigFilename (const FcChar8 *url);
+
+FcPublic FcConfig *
+FcConfigCreate (void);
+
+FcPublic FcConfig *
+FcConfigReference (FcConfig *config);
+
+FcPublic void
+FcConfigDestroy (FcConfig *config);
+
+FcPublic FcBool
+FcConfigSetCurrent (FcConfig *config);
+
+FcPublic FcConfig *
+FcConfigGetCurrent (void);
+
+FcPublic FcBool
+FcConfigUptoDate (FcConfig *config);
+
+FcPublic FcBool
+FcConfigBuildFonts (FcConfig *config);
+
+FcPublic FcStrList *
+FcConfigGetFontDirs (FcConfig *config);
+
+FcPublic FcStrList *
+FcConfigGetConfigDirs (FcConfig *config);
+
+FcPublic FcStrList *
+FcConfigGetConfigFiles (FcConfig *config);
+
+FcPublic FcChar8 *
+FcConfigGetCache (FcConfig *config);
+
+FcPublic FcBlanks *
+FcConfigGetBlanks (FcConfig *config);
+
+FcPublic FcStrList *
+FcConfigGetCacheDirs (FcConfig *config);
+
+FcPublic int
+FcConfigGetRescanInterval (FcConfig *config);
+
+FcPublic FcBool
+FcConfigSetRescanInterval (FcConfig *config, int rescanInterval);
+
+FcPublic FcFontSet *
+FcConfigGetFonts (FcConfig *config,
+ FcSetName set);
+
+FcPublic FcBool
+FcConfigAppFontAddFile (FcConfig *config,
+ const FcChar8 *file);
+
+FcPublic FcBool
+FcConfigAppFontAddDir (FcConfig *config,
+ const FcChar8 *dir);
+
+FcPublic void
+FcConfigAppFontClear (FcConfig *config);
+
+FcPublic FcBool
+FcConfigSubstituteWithPat (FcConfig *config,
+ FcPattern *p,
+ FcPattern *p_pat,
+ FcMatchKind kind);
+
+FcPublic FcBool
+FcConfigSubstitute (FcConfig *config,
+ FcPattern *p,
+ FcMatchKind kind);
+
+FcPublic const FcChar8 *
+FcConfigGetSysRoot (const FcConfig *config);
+
+FcPublic void
+FcConfigSetSysRoot (FcConfig *config,
+ const FcChar8 *sysroot);
+
+FcPublic void
+FcConfigFileInfoIterInit (FcConfig *config,
+ FcConfigFileInfoIter *iter);
+
+FcPublic FcBool
+FcConfigFileInfoIterNext (FcConfig *config,
+ FcConfigFileInfoIter *iter);
+
+FcPublic FcBool
+FcConfigFileInfoIterGet (FcConfig *config,
+ FcConfigFileInfoIter *iter,
+ FcChar8 **name,
+ FcChar8 **description,
+ FcBool *enabled);
+
+/* fccharset.c */
+FcPublic FcCharSet*
+FcCharSetCreate (void);
+
+/* deprecated alias for FcCharSetCreate */
+FcPublic FcCharSet *
+FcCharSetNew (void);
+
+FcPublic void
+FcCharSetDestroy (FcCharSet *fcs);
+
+FcPublic FcBool
+FcCharSetAddChar (FcCharSet *fcs, FcChar32 ucs4);
+
+FcPublic FcBool
+FcCharSetDelChar (FcCharSet *fcs, FcChar32 ucs4);
+
+FcPublic FcCharSet*
+FcCharSetCopy (FcCharSet *src);
+
+FcPublic FcBool
+FcCharSetEqual (const FcCharSet *a, const FcCharSet *b);
+
+FcPublic FcCharSet*
+FcCharSetIntersect (const FcCharSet *a, const FcCharSet *b);
+
+FcPublic FcCharSet*
+FcCharSetUnion (const FcCharSet *a, const FcCharSet *b);
+
+FcPublic FcCharSet*
+FcCharSetSubtract (const FcCharSet *a, const FcCharSet *b);
+
+FcPublic FcBool
+FcCharSetMerge (FcCharSet *a, const FcCharSet *b, FcBool *changed);
+
+FcPublic FcBool
+FcCharSetHasChar (const FcCharSet *fcs, FcChar32 ucs4);
+
+FcPublic FcChar32
+FcCharSetCount (const FcCharSet *a);
+
+FcPublic FcChar32
+FcCharSetIntersectCount (const FcCharSet *a, const FcCharSet *b);
+
+FcPublic FcChar32
+FcCharSetSubtractCount (const FcCharSet *a, const FcCharSet *b);
+
+FcPublic FcBool
+FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b);
+
+#define FC_CHARSET_MAP_SIZE (256/32)
+#define FC_CHARSET_DONE ((FcChar32) -1)
+
+FcPublic FcChar32
+FcCharSetFirstPage (const FcCharSet *a,
+ FcChar32 map[FC_CHARSET_MAP_SIZE],
+ FcChar32 *next);
+
+FcPublic FcChar32
+FcCharSetNextPage (const FcCharSet *a,
+ FcChar32 map[FC_CHARSET_MAP_SIZE],
+ FcChar32 *next);
+
+/*
+ * old coverage API, rather hard to use correctly
+ */
+
+FcPublic FcChar32
+FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result);
+
+/* fcdbg.c */
+FcPublic void
+FcValuePrint (const FcValue v);
+
+FcPublic void
+FcPatternPrint (const FcPattern *p);
+
+FcPublic void
+FcFontSetPrint (const FcFontSet *s);
+
+/* fcdefault.c */
+FcPublic FcStrSet *
+FcGetDefaultLangs (void);
+
+FcPublic void
+FcDefaultSubstitute (FcPattern *pattern);
+
+/* fcdir.c */
+FcPublic FcBool
+FcFileIsDir (const FcChar8 *file);
+
+FcPublic FcBool
+FcFileScan (FcFontSet *set,
+ FcStrSet *dirs,
+ FcFileCache *cache,
+ FcBlanks *blanks,
+ const FcChar8 *file,
+ FcBool force);
+
+FcPublic FcBool
+FcDirScan (FcFontSet *set,
+ FcStrSet *dirs,
+ FcFileCache *cache,
+ FcBlanks *blanks,
+ const FcChar8 *dir,
+ FcBool force);
+
+FcPublic FcBool
+FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir);
+
+FcPublic FcCache *
+FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file);
+
+FcPublic FcCache *
+FcDirCacheRescan (const FcChar8 *dir, FcConfig *config);
+
+FcPublic FcCache *
+FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config);
+
+FcPublic FcCache *
+FcDirCacheLoadFile (const FcChar8 *cache_file, struct stat *file_stat);
+
+FcPublic void
+FcDirCacheUnload (FcCache *cache);
+
+/* fcfreetype.c */
+FcPublic FcPattern *
+FcFreeTypeQuery (const FcChar8 *file, unsigned int id, FcBlanks *blanks, int *count);
+
+FcPublic unsigned int
+FcFreeTypeQueryAll(const FcChar8 *file, unsigned int id, FcBlanks *blanks, int *count, FcFontSet *set);
+
+/* fcfs.c */
+
+FcPublic FcFontSet *
+FcFontSetCreate (void);
+
+FcPublic void
+FcFontSetDestroy (FcFontSet *s);
+
+FcPublic FcBool
+FcFontSetAdd (FcFontSet *s, FcPattern *font);
+
+/* fcinit.c */
+FcPublic FcConfig *
+FcInitLoadConfig (void);
+
+FcPublic FcConfig *
+FcInitLoadConfigAndFonts (void);
+
+FcPublic FcBool
+FcInit (void);
+
+FcPublic void
+FcFini (void);
+
+FcPublic int
+FcGetVersion (void);
+
+FcPublic FcBool
+FcInitReinitialize (void);
+
+FcPublic FcBool
+FcInitBringUptoDate (void);
+
+/* fclang.c */
+FcPublic FcStrSet *
+FcGetLangs (void);
+
+FcPublic FcChar8 *
+FcLangNormalize (const FcChar8 *lang);
+
+FcPublic const FcCharSet *
+FcLangGetCharSet (const FcChar8 *lang);
+
+FcPublic FcLangSet*
+FcLangSetCreate (void);
+
+FcPublic void
+FcLangSetDestroy (FcLangSet *ls);
+
+FcPublic FcLangSet*
+FcLangSetCopy (const FcLangSet *ls);
+
+FcPublic FcBool
+FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang);
+
+FcPublic FcBool
+FcLangSetDel (FcLangSet *ls, const FcChar8 *lang);
+
+FcPublic FcLangResult
+FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang);
+
+FcPublic FcLangResult
+FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb);
+
+FcPublic FcBool
+FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb);
+
+FcPublic FcBool
+FcLangSetEqual (const FcLangSet *lsa, const FcLangSet *lsb);
+
+FcPublic FcChar32
+FcLangSetHash (const FcLangSet *ls);
+
+FcPublic FcStrSet *
+FcLangSetGetLangs (const FcLangSet *ls);
+
+FcPublic FcLangSet *
+FcLangSetUnion (const FcLangSet *a, const FcLangSet *b);
+
+FcPublic FcLangSet *
+FcLangSetSubtract (const FcLangSet *a, const FcLangSet *b);
+
+/* fclist.c */
+FcPublic FcObjectSet *
+FcObjectSetCreate (void);
+
+FcPublic FcBool
+FcObjectSetAdd (FcObjectSet *os, const char *object);
+
+FcPublic void
+FcObjectSetDestroy (FcObjectSet *os);
+
+FcPublic FcObjectSet *
+FcObjectSetVaBuild (const char *first, va_list va);
+
+FcPublic FcObjectSet *
+FcObjectSetBuild (const char *first, ...) FC_ATTRIBUTE_SENTINEL(0);
+
+FcPublic FcFontSet *
+FcFontSetList (FcConfig *config,
+ FcFontSet **sets,
+ int nsets,
+ FcPattern *p,
+ FcObjectSet *os);
+
+FcPublic FcFontSet *
+FcFontList (FcConfig *config,
+ FcPattern *p,
+ FcObjectSet *os);
+
+/* fcatomic.c */
+
+FcPublic FcAtomic *
+FcAtomicCreate (const FcChar8 *file);
+
+FcPublic FcBool
+FcAtomicLock (FcAtomic *atomic);
+
+FcPublic FcChar8 *
+FcAtomicNewFile (FcAtomic *atomic);
+
+FcPublic FcChar8 *
+FcAtomicOrigFile (FcAtomic *atomic);
+
+FcPublic FcBool
+FcAtomicReplaceOrig (FcAtomic *atomic);
+
+FcPublic void
+FcAtomicDeleteNew (FcAtomic *atomic);
+
+FcPublic void
+FcAtomicUnlock (FcAtomic *atomic);
+
+FcPublic void
+FcAtomicDestroy (FcAtomic *atomic);
+
+/* fcmatch.c */
+FcPublic FcPattern *
+FcFontSetMatch (FcConfig *config,
+ FcFontSet **sets,
+ int nsets,
+ FcPattern *p,
+ FcResult *result);
+
+FcPublic FcPattern *
+FcFontMatch (FcConfig *config,
+ FcPattern *p,
+ FcResult *result);
+
+FcPublic FcPattern *
+FcFontRenderPrepare (FcConfig *config,
+ FcPattern *pat,
+ FcPattern *font);
+
+FcPublic FcFontSet *
+FcFontSetSort (FcConfig *config,
+ FcFontSet **sets,
+ int nsets,
+ FcPattern *p,
+ FcBool trim,
+ FcCharSet **csp,
+ FcResult *result);
+
+FcPublic FcFontSet *
+FcFontSort (FcConfig *config,
+ FcPattern *p,
+ FcBool trim,
+ FcCharSet **csp,
+ FcResult *result);
+
+FcPublic void
+FcFontSetSortDestroy (FcFontSet *fs);
+
+/* fcmatrix.c */
+FcPublic FcMatrix *
+FcMatrixCopy (const FcMatrix *mat);
+
+FcPublic FcBool
+FcMatrixEqual (const FcMatrix *mat1, const FcMatrix *mat2);
+
+FcPublic void
+FcMatrixMultiply (FcMatrix *result, const FcMatrix *a, const FcMatrix *b);
+
+FcPublic void
+FcMatrixRotate (FcMatrix *m, double c, double s);
+
+FcPublic void
+FcMatrixScale (FcMatrix *m, double sx, double sy);
+
+FcPublic void
+FcMatrixShear (FcMatrix *m, double sh, double sv);
+
+/* fcname.c */
+
+/* Deprecated. Does nothing. Returns FcFalse. */
+FcPublic FcBool
+FcNameRegisterObjectTypes (const FcObjectType *types, int ntype);
+
+/* Deprecated. Does nothing. Returns FcFalse. */
+FcPublic FcBool
+FcNameUnregisterObjectTypes (const FcObjectType *types, int ntype);
+
+FcPublic const FcObjectType *
+FcNameGetObjectType (const char *object);
+
+/* Deprecated. Does nothing. Returns FcFalse. */
+FcPublic FcBool
+FcNameRegisterConstants (const FcConstant *consts, int nconsts);
+
+/* Deprecated. Does nothing. Returns FcFalse. */
+FcPublic FcBool
+FcNameUnregisterConstants (const FcConstant *consts, int nconsts);
+
+FcPublic const FcConstant *
+FcNameGetConstant (const FcChar8 *string);
+
+FcPublic FcBool
+FcNameConstant (const FcChar8 *string, int *result);
+
+FcPublic FcPattern *
+FcNameParse (const FcChar8 *name);
+
+FcPublic FcChar8 *
+FcNameUnparse (FcPattern *pat);
+
+/* fcpat.c */
+FcPublic FcPattern *
+FcPatternCreate (void);
+
+FcPublic FcPattern *
+FcPatternDuplicate (const FcPattern *p);
+
+FcPublic void
+FcPatternReference (FcPattern *p);
+
+FcPublic FcPattern *
+FcPatternFilter (FcPattern *p, const FcObjectSet *os);
+
+FcPublic void
+FcValueDestroy (FcValue v);
+
+FcPublic FcBool
+FcValueEqual (FcValue va, FcValue vb);
+
+FcPublic FcValue
+FcValueSave (FcValue v);
+
+FcPublic void
+FcPatternDestroy (FcPattern *p);
+
+int
+FcPatternObjectCount (const FcPattern *pat);
+
+FcPublic FcBool
+FcPatternEqual (const FcPattern *pa, const FcPattern *pb);
+
+FcPublic FcBool
+FcPatternEqualSubset (const FcPattern *pa, const FcPattern *pb, const FcObjectSet *os);
+
+FcPublic FcChar32
+FcPatternHash (const FcPattern *p);
+
+FcPublic FcBool
+FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append);
+
+FcPublic FcBool
+FcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append);
+
+FcPublic FcResult
+FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v);
+
+FcPublic FcResult
+FcPatternGetWithBinding (const FcPattern *p, const char *object, int id, FcValue *v, FcValueBinding *b);
+
+FcPublic FcBool
+FcPatternDel (FcPattern *p, const char *object);
+
+FcPublic FcBool
+FcPatternRemove (FcPattern *p, const char *object, int id);
+
+FcPublic FcBool
+FcPatternAddInteger (FcPattern *p, const char *object, int i);
+
+FcPublic FcBool
+FcPatternAddDouble (FcPattern *p, const char *object, double d);
+
+FcPublic FcBool
+FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s);
+
+FcPublic FcBool
+FcPatternAddMatrix (FcPattern *p, const char *object, const FcMatrix *s);
+
+FcPublic FcBool
+FcPatternAddCharSet (FcPattern *p, const char *object, const FcCharSet *c);
+
+FcPublic FcBool
+FcPatternAddBool (FcPattern *p, const char *object, FcBool b);
+
+FcPublic FcBool
+FcPatternAddLangSet (FcPattern *p, const char *object, const FcLangSet *ls);
+
+FcPublic FcBool
+FcPatternAddRange (FcPattern *p, const char *object, const FcRange *r);
+
+FcPublic FcResult
+FcPatternGetInteger (const FcPattern *p, const char *object, int n, int *i);
+
+FcPublic FcResult
+FcPatternGetDouble (const FcPattern *p, const char *object, int n, double *d);
+
+FcPublic FcResult
+FcPatternGetString (const FcPattern *p, const char *object, int n, FcChar8 ** s);
+
+FcPublic FcResult
+FcPatternGetMatrix (const FcPattern *p, const char *object, int n, FcMatrix **s);
+
+FcPublic FcResult
+FcPatternGetCharSet (const FcPattern *p, const char *object, int n, FcCharSet **c);
+
+FcPublic FcResult
+FcPatternGetBool (const FcPattern *p, const char *object, int n, FcBool *b);
+
+FcPublic FcResult
+FcPatternGetLangSet (const FcPattern *p, const char *object, int n, FcLangSet **ls);
+
+FcPublic FcResult
+FcPatternGetRange (const FcPattern *p, const char *object, int id, FcRange **r);
+
+FcPublic FcPattern *
+FcPatternVaBuild (FcPattern *p, va_list va);
+
+FcPublic FcPattern *
+FcPatternBuild (FcPattern *p, ...) FC_ATTRIBUTE_SENTINEL(0);
+
+FcPublic FcChar8 *
+FcPatternFormat (FcPattern *pat, const FcChar8 *format);
+
+/* fcrange.c */
+FcPublic FcRange *
+FcRangeCreateDouble (double begin, double end);
+
+FcPublic FcRange *
+FcRangeCreateInteger (FcChar32 begin, FcChar32 end);
+
+FcPublic void
+FcRangeDestroy (FcRange *range);
+
+FcPublic FcRange *
+FcRangeCopy (const FcRange *r);
+
+FcPublic FcBool
+FcRangeGetDouble(const FcRange *range, double *begin, double *end);
+
+FcPublic void
+FcPatternIterStart (const FcPattern *pat, FcPatternIter *iter);
+
+FcPublic FcBool
+FcPatternIterNext (const FcPattern *pat, FcPatternIter *iter);
+
+FcPublic FcBool
+FcPatternIterEqual (const FcPattern *p1, FcPatternIter *i1,
+ const FcPattern *p2, FcPatternIter *i2);
+
+FcPublic FcBool
+FcPatternFindIter (const FcPattern *pat, FcPatternIter *iter, const char *object);
+
+FcPublic FcBool
+FcPatternIterIsValid (const FcPattern *pat, FcPatternIter *iter);
+
+FcPublic const char *
+FcPatternIterGetObject (const FcPattern *pat, FcPatternIter *iter);
+
+FcPublic int
+FcPatternIterValueCount (const FcPattern *pat, FcPatternIter *iter);
+
+FcPublic FcResult
+FcPatternIterGetValue (const FcPattern *pat, FcPatternIter *iter, int id, FcValue *v, FcValueBinding *b);
+
+/* fcweight.c */
+
+FcPublic int
+FcWeightFromOpenType (int ot_weight);
+
+FcPublic double
+FcWeightFromOpenTypeDouble (double ot_weight);
+
+FcPublic int
+FcWeightToOpenType (int fc_weight);
+
+FcPublic double
+FcWeightToOpenTypeDouble (double fc_weight);
+
+/* fcstr.c */
+
+FcPublic FcChar8 *
+FcStrCopy (const FcChar8 *s);
+
+FcPublic FcChar8 *
+FcStrCopyFilename (const FcChar8 *s);
+
+FcPublic FcChar8 *
+FcStrPlus (const FcChar8 *s1, const FcChar8 *s2);
+
+FcPublic void
+FcStrFree (FcChar8 *s);
+
+/* These are ASCII only, suitable only for pattern element names */
+#define FcIsUpper(c) ((0101 <= (c) && (c) <= 0132))
+#define FcIsLower(c) ((0141 <= (c) && (c) <= 0172))
+#define FcToLower(c) (FcIsUpper(c) ? (c) - 0101 + 0141 : (c))
+
+FcPublic FcChar8 *
+FcStrDowncase (const FcChar8 *s);
+
+FcPublic int
+FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
+
+FcPublic int
+FcStrCmp (const FcChar8 *s1, const FcChar8 *s2);
+
+FcPublic const FcChar8 *
+FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
+
+FcPublic const FcChar8 *
+FcStrStr (const FcChar8 *s1, const FcChar8 *s2);
+
+FcPublic int
+FcUtf8ToUcs4 (const FcChar8 *src_orig,
+ FcChar32 *dst,
+ int len);
+
+FcPublic FcBool
+FcUtf8Len (const FcChar8 *string,
+ int len,
+ int *nchar,
+ int *wchar);
+
+#define FC_UTF8_MAX_LEN 6
+
+FcPublic int
+FcUcs4ToUtf8 (FcChar32 ucs4,
+ FcChar8 dest[FC_UTF8_MAX_LEN]);
+
+FcPublic int
+FcUtf16ToUcs4 (const FcChar8 *src_orig,
+ FcEndian endian,
+ FcChar32 *dst,
+ int len); /* in bytes */
+
+FcPublic FcBool
+FcUtf16Len (const FcChar8 *string,
+ FcEndian endian,
+ int len, /* in bytes */
+ int *nchar,
+ int *wchar);
+
+FcPublic FcChar8 *
+FcStrBuildFilename (const FcChar8 *path,
+ ...);
+
+FcPublic FcChar8 *
+FcStrDirname (const FcChar8 *file);
+
+FcPublic FcChar8 *
+FcStrBasename (const FcChar8 *file);
+
+FcPublic FcStrSet *
+FcStrSetCreate (void);
+
+FcPublic FcBool
+FcStrSetMember (FcStrSet *set, const FcChar8 *s);
+
+FcPublic FcBool
+FcStrSetEqual (FcStrSet *sa, FcStrSet *sb);
+
+FcPublic FcBool
+FcStrSetAdd (FcStrSet *set, const FcChar8 *s);
+
+FcPublic FcBool
+FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s);
+
+FcPublic FcBool
+FcStrSetDel (FcStrSet *set, const FcChar8 *s);
+
+FcPublic void
+FcStrSetDestroy (FcStrSet *set);
+
+FcPublic FcStrList *
+FcStrListCreate (FcStrSet *set);
+
+FcPublic void
+FcStrListFirst (FcStrList *list);
+
+FcPublic FcChar8 *
+FcStrListNext (FcStrList *list);
+
+FcPublic void
+FcStrListDone (FcStrList *list);
+
+/* fcxml.c */
+FcPublic FcBool
+FcConfigParseAndLoad (FcConfig *config, const FcChar8 *file, FcBool complain);
+
+FcPublic FcBool
+FcConfigParseAndLoadFromMemory (FcConfig *config,
+ const FcChar8 *buffer,
+ FcBool complain);
+
+_FCFUNCPROTOEND
+
+#undef FC_ATTRIBUTE_SENTINEL
+
+
+#ifndef _FCINT_H_
+
+/*
+ * Deprecated functions are placed here to help users fix their code without
+ * digging through documentation
+ */
+
+#define FcConfigGetRescanInverval FcConfigGetRescanInverval_REPLACE_BY_FcConfigGetRescanInterval
+#define FcConfigSetRescanInverval FcConfigSetRescanInverval_REPLACE_BY_FcConfigSetRescanInterval
+
+#endif
+
+#endif /* _FONTCONFIG_H_ */
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftconfig.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftconfig.h
new file mode 100644
index 0000000..c696e90
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftconfig.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+ *
+ * ftconfig.h
+ *
+ * ANSI-specific configuration file (specification only).
+ *
+ * Copyright (C) 1996-2022 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+ /**************************************************************************
+ *
+ * This header file contains a number of macro definitions that are used by
+ * the rest of the engine. Most of the macros here are automatically
+ * determined at compile time, and you should not need to change it to port
+ * FreeType, except to compile the library with a non-ANSI compiler.
+ *
+ * Note however that if some specific modifications are needed, we advise
+ * you to place a modified copy in your build directory.
+ *
+ * The build directory is usually `builds/`, and contains
+ * system-specific files that are always included first when building the
+ * library.
+ *
+ * This ANSI version should stay in `include/config/`.
+ *
+ */
+
+#ifndef FTCONFIG_H_
+#define FTCONFIG_H_
+
+#include
+#include FT_CONFIG_OPTIONS_H
+#include FT_CONFIG_STANDARD_LIBRARY_H
+
+#include
+#include
+#include
+
+#endif /* FTCONFIG_H_ */
+
+
+/* END */
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftheader.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftheader.h
new file mode 100644
index 0000000..a8c6833
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftheader.h
@@ -0,0 +1,836 @@
+/****************************************************************************
+ *
+ * ftheader.h
+ *
+ * Build macros of the FreeType 2 library.
+ *
+ * Copyright (C) 1996-2022 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+#ifndef FTHEADER_H_
+#define FTHEADER_H_
+
+
+ /*@***********************************************************************/
+ /* */
+ /* */
+ /* FT_BEGIN_HEADER */
+ /* */
+ /* */
+ /* This macro is used in association with @FT_END_HEADER in header */
+ /* files to ensure that the declarations within are properly */
+ /* encapsulated in an `extern "C" { .. }` block when included from a */
+ /* C++ compiler. */
+ /* */
+#ifndef FT_BEGIN_HEADER
+# ifdef __cplusplus
+# define FT_BEGIN_HEADER extern "C" {
+# else
+# define FT_BEGIN_HEADER /* nothing */
+# endif
+#endif
+
+
+ /*@***********************************************************************/
+ /* */
+ /* */
+ /* FT_END_HEADER */
+ /* */
+ /* */
+ /* This macro is used in association with @FT_BEGIN_HEADER in header */
+ /* files to ensure that the declarations within are properly */
+ /* encapsulated in an `extern "C" { .. }` block when included from a */
+ /* C++ compiler. */
+ /* */
+#ifndef FT_END_HEADER
+# ifdef __cplusplus
+# define FT_END_HEADER }
+# else
+# define FT_END_HEADER /* nothing */
+# endif
+#endif
+
+
+ /**************************************************************************
+ *
+ * Aliases for the FreeType 2 public and configuration files.
+ *
+ */
+
+ /**************************************************************************
+ *
+ * @section:
+ * header_file_macros
+ *
+ * @title:
+ * Header File Macros
+ *
+ * @abstract:
+ * Macro definitions used to `#include` specific header files.
+ *
+ * @description:
+ * In addition to the normal scheme of including header files like
+ *
+ * ```
+ * #include
+ * #include
+ * #include
+ * ```
+ *
+ * it is possible to used named macros instead. They can be used
+ * directly in `#include` statements as in
+ *
+ * ```
+ * #include FT_FREETYPE_H
+ * #include FT_MULTIPLE_MASTERS_H
+ * #include FT_GLYPH_H
+ * ```
+ *
+ * These macros were introduced to overcome the infamous 8.3~naming rule
+ * required by DOS (and `FT_MULTIPLE_MASTERS_H` is a lot more meaningful
+ * than `ftmm.h`).
+ *
+ */
+
+
+ /* configuration files */
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_CONFIG_CONFIG_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing
+ * FreeType~2 configuration data.
+ *
+ */
+#ifndef FT_CONFIG_CONFIG_H
+#define FT_CONFIG_CONFIG_H
+#endif
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_CONFIG_STANDARD_LIBRARY_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing
+ * FreeType~2 interface to the standard C library functions.
+ *
+ */
+#ifndef FT_CONFIG_STANDARD_LIBRARY_H
+#define FT_CONFIG_STANDARD_LIBRARY_H
+#endif
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_CONFIG_OPTIONS_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing
+ * FreeType~2 project-specific configuration options.
+ *
+ */
+#ifndef FT_CONFIG_OPTIONS_H
+#define FT_CONFIG_OPTIONS_H
+#endif
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_CONFIG_MODULES_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * list of FreeType~2 modules that are statically linked to new library
+ * instances in @FT_Init_FreeType.
+ *
+ */
+#ifndef FT_CONFIG_MODULES_H
+#define FT_CONFIG_MODULES_H
+#endif
+
+ /* */
+
+ /* public headers */
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_FREETYPE_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * base FreeType~2 API.
+ *
+ */
+#define FT_FREETYPE_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_ERRORS_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * list of FreeType~2 error codes (and messages).
+ *
+ * It is included by @FT_FREETYPE_H.
+ *
+ */
+#define FT_ERRORS_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_MODULE_ERRORS_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * list of FreeType~2 module error offsets (and messages).
+ *
+ */
+#define FT_MODULE_ERRORS_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_SYSTEM_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * FreeType~2 interface to low-level operations (i.e., memory management
+ * and stream i/o).
+ *
+ * It is included by @FT_FREETYPE_H.
+ *
+ */
+#define FT_SYSTEM_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_IMAGE_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing type
+ * definitions related to glyph images (i.e., bitmaps, outlines,
+ * scan-converter parameters).
+ *
+ * It is included by @FT_FREETYPE_H.
+ *
+ */
+#define FT_IMAGE_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_TYPES_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * basic data types defined by FreeType~2.
+ *
+ * It is included by @FT_FREETYPE_H.
+ *
+ */
+#define FT_TYPES_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_LIST_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * list management API of FreeType~2.
+ *
+ * (Most applications will never need to include this file.)
+ *
+ */
+#define FT_LIST_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_OUTLINE_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * scalable outline management API of FreeType~2.
+ *
+ */
+#define FT_OUTLINE_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_SIZES_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * API which manages multiple @FT_Size objects per face.
+ *
+ */
+#define FT_SIZES_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_MODULE_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * module management API of FreeType~2.
+ *
+ */
+#define FT_MODULE_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_RENDER_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * renderer module management API of FreeType~2.
+ *
+ */
+#define FT_RENDER_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_DRIVER_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing
+ * structures and macros related to the driver modules.
+ *
+ */
+#define FT_DRIVER_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_AUTOHINTER_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing
+ * structures and macros related to the auto-hinting module.
+ *
+ * Deprecated since version~2.9; use @FT_DRIVER_H instead.
+ *
+ */
+#define FT_AUTOHINTER_H FT_DRIVER_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_CFF_DRIVER_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing
+ * structures and macros related to the CFF driver module.
+ *
+ * Deprecated since version~2.9; use @FT_DRIVER_H instead.
+ *
+ */
+#define FT_CFF_DRIVER_H FT_DRIVER_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_TRUETYPE_DRIVER_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing
+ * structures and macros related to the TrueType driver module.
+ *
+ * Deprecated since version~2.9; use @FT_DRIVER_H instead.
+ *
+ */
+#define FT_TRUETYPE_DRIVER_H FT_DRIVER_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_PCF_DRIVER_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing
+ * structures and macros related to the PCF driver module.
+ *
+ * Deprecated since version~2.9; use @FT_DRIVER_H instead.
+ *
+ */
+#define FT_PCF_DRIVER_H FT_DRIVER_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_TYPE1_TABLES_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * types and API specific to the Type~1 format.
+ *
+ */
+#define FT_TYPE1_TABLES_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_TRUETYPE_IDS_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * enumeration values which identify name strings, languages, encodings,
+ * etc. This file really contains a _large_ set of constant macro
+ * definitions, taken from the TrueType and OpenType specifications.
+ *
+ */
+#define FT_TRUETYPE_IDS_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_TRUETYPE_TABLES_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * types and API specific to the TrueType (as well as OpenType) format.
+ *
+ */
+#define FT_TRUETYPE_TABLES_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_TRUETYPE_TAGS_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * definitions of TrueType four-byte 'tags' which identify blocks in
+ * SFNT-based font formats (i.e., TrueType and OpenType).
+ *
+ */
+#define FT_TRUETYPE_TAGS_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_BDF_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * definitions of an API which accesses BDF-specific strings from a face.
+ *
+ */
+#define FT_BDF_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_CID_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * definitions of an API which access CID font information from a face.
+ *
+ */
+#define FT_CID_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_GZIP_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * definitions of an API which supports gzip-compressed files.
+ *
+ */
+#define FT_GZIP_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_LZW_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * definitions of an API which supports LZW-compressed files.
+ *
+ */
+#define FT_LZW_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_BZIP2_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * definitions of an API which supports bzip2-compressed files.
+ *
+ */
+#define FT_BZIP2_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_WINFONTS_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * definitions of an API which supports Windows FNT files.
+ *
+ */
+#define FT_WINFONTS_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_GLYPH_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * API of the optional glyph management component.
+ *
+ */
+#define FT_GLYPH_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_BITMAP_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * API of the optional bitmap conversion component.
+ *
+ */
+#define FT_BITMAP_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_BBOX_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * API of the optional exact bounding box computation routines.
+ *
+ */
+#define FT_BBOX_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_CACHE_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * API of the optional FreeType~2 cache sub-system.
+ *
+ */
+#define FT_CACHE_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_MAC_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * Macintosh-specific FreeType~2 API. The latter is used to access fonts
+ * embedded in resource forks.
+ *
+ * This header file must be explicitly included by client applications
+ * compiled on the Mac (note that the base API still works though).
+ *
+ */
+#define FT_MAC_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_MULTIPLE_MASTERS_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * optional multiple-masters management API of FreeType~2.
+ *
+ */
+#define FT_MULTIPLE_MASTERS_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_SFNT_NAMES_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * optional FreeType~2 API which accesses embedded 'name' strings in
+ * SFNT-based font formats (i.e., TrueType and OpenType).
+ *
+ */
+#define FT_SFNT_NAMES_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_OPENTYPE_VALIDATE_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * optional FreeType~2 API which validates OpenType tables ('BASE',
+ * 'GDEF', 'GPOS', 'GSUB', 'JSTF').
+ *
+ */
+#define FT_OPENTYPE_VALIDATE_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_GX_VALIDATE_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * optional FreeType~2 API which validates TrueTypeGX/AAT tables ('feat',
+ * 'mort', 'morx', 'bsln', 'just', 'kern', 'opbd', 'trak', 'prop').
+ *
+ */
+#define FT_GX_VALIDATE_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_PFR_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * FreeType~2 API which accesses PFR-specific data.
+ *
+ */
+#define FT_PFR_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_STROKER_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * FreeType~2 API which provides functions to stroke outline paths.
+ */
+#define FT_STROKER_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_SYNTHESIS_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * FreeType~2 API which performs artificial obliquing and emboldening.
+ */
+#define FT_SYNTHESIS_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_FONT_FORMATS_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * FreeType~2 API which provides functions specific to font formats.
+ */
+#define FT_FONT_FORMATS_H
+
+ /* deprecated */
+#define FT_XFREE86_H FT_FONT_FORMATS_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_TRIGONOMETRY_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * FreeType~2 API which performs trigonometric computations (e.g.,
+ * cosines and arc tangents).
+ */
+#define FT_TRIGONOMETRY_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_LCD_FILTER_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * FreeType~2 API which performs color filtering for subpixel rendering.
+ */
+#define FT_LCD_FILTER_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_INCREMENTAL_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * FreeType~2 API which performs incremental glyph loading.
+ */
+#define FT_INCREMENTAL_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_GASP_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * FreeType~2 API which returns entries from the TrueType GASP table.
+ */
+#define FT_GASP_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_ADVANCES_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * FreeType~2 API which returns individual and ranged glyph advances.
+ */
+#define FT_ADVANCES_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_COLOR_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * FreeType~2 API which handles the OpenType 'CPAL' table.
+ */
+#define FT_COLOR_H
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_OTSVG_H
+ *
+ * @description:
+ * A macro used in `#include` statements to name the file containing the
+ * FreeType~2 API which handles the OpenType 'SVG~' glyphs.
+ */
+#define FT_OTSVG_H
+
+
+ /* */
+
+ /* These header files don't need to be included by the user. */
+#define FT_ERROR_DEFINITIONS_H
+#define FT_PARAMETER_TAGS_H
+
+ /* Deprecated macros. */
+#define FT_UNPATENTED_HINTING_H
+#define FT_TRUETYPE_UNPATENTED_H
+
+ /* `FT_CACHE_H` is the only header file needed for the cache subsystem. */
+#define FT_CACHE_IMAGE_H FT_CACHE_H
+#define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H
+#define FT_CACHE_CHARMAP_H FT_CACHE_H
+
+ /* The internals of the cache sub-system are no longer exposed. We */
+ /* default to `FT_CACHE_H` at the moment just in case, but we know */
+ /* of no rogue client that uses them. */
+ /* */
+#define FT_CACHE_MANAGER_H FT_CACHE_H
+#define FT_CACHE_INTERNAL_MRU_H FT_CACHE_H
+#define FT_CACHE_INTERNAL_MANAGER_H FT_CACHE_H
+#define FT_CACHE_INTERNAL_CACHE_H FT_CACHE_H
+#define FT_CACHE_INTERNAL_GLYPH_H FT_CACHE_H
+#define FT_CACHE_INTERNAL_IMAGE_H FT_CACHE_H
+#define FT_CACHE_INTERNAL_SBITS_H FT_CACHE_H
+
+/* TODO(david): Move this section below to a different header */
+#ifdef FT2_BUILD_LIBRARY
+#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
+
+ /* We disable the warning `conditional expression is constant' here */
+ /* in order to compile cleanly with the maximum level of warnings. */
+ /* In particular, the warning complains about stuff like `while(0)' */
+ /* which is very useful in macro definitions. There is no benefit */
+ /* in having it enabled. */
+#pragma warning( disable : 4127 )
+
+#endif /* _MSC_VER */
+#endif /* FT2_BUILD_LIBRARY */
+
+#endif /* FTHEADER_H_ */
+
+
+/* END */
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftmodule.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftmodule.h
new file mode 100644
index 0000000..6bd4f9a
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftmodule.h
@@ -0,0 +1,20 @@
+/* This is a generated file. */
+FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class )
+FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class )
+FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class )
+FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class )
+FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class )
+FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class )
+FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class )
+FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class )
+FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )
+FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
+FT_USE_MODULE( FT_Module_Class, autofit_module_class )
+FT_USE_MODULE( FT_Module_Class, pshinter_module_class )
+FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
+FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )
+FT_USE_MODULE( FT_Renderer_Class, ft_svg_renderer_class )
+FT_USE_MODULE( FT_Renderer_Class, None_renderer_class )
+FT_USE_MODULE( FT_Module_Class, psaux_module_class )
+FT_USE_MODULE( FT_Module_Class, psnames_module_class )
+/* EOF */
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftoption.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftoption.h
new file mode 100644
index 0000000..209a427
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftoption.h
@@ -0,0 +1,1029 @@
+/****************************************************************************
+ *
+ * ftoption.h
+ *
+ * User-selectable configuration macros (specification only).
+ *
+ * Copyright (C) 1996-2022 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+#ifndef FTOPTION_H_
+#define FTOPTION_H_
+
+
+#include
+
+
+FT_BEGIN_HEADER
+
+ /**************************************************************************
+ *
+ * USER-SELECTABLE CONFIGURATION MACROS
+ *
+ * This file contains the default configuration macro definitions for a
+ * standard build of the FreeType library. There are three ways to use
+ * this file to build project-specific versions of the library:
+ *
+ * - You can modify this file by hand, but this is not recommended in
+ * cases where you would like to build several versions of the library
+ * from a single source directory.
+ *
+ * - You can put a copy of this file in your build directory, more
+ * precisely in `$BUILD/freetype/config/ftoption.h`, where `$BUILD` is
+ * the name of a directory that is included _before_ the FreeType include
+ * path during compilation.
+ *
+ * The default FreeType Makefiles use the build directory
+ * `builds/` by default, but you can easily change that for your
+ * own projects.
+ *
+ * - Copy the file to `$BUILD/ft2build.h` and modify it
+ * slightly to pre-define the macro `FT_CONFIG_OPTIONS_H` used to locate
+ * this file during the build. For example,
+ *
+ * ```
+ * #define FT_CONFIG_OPTIONS_H
+ * #include
+ * ```
+ *
+ * will use `$BUILD/myftoptions.h` instead of this file for macro
+ * definitions.
+ *
+ * Note also that you can similarly pre-define the macro
+ * `FT_CONFIG_MODULES_H` used to locate the file listing of the modules
+ * that are statically linked to the library at compile time. By
+ * default, this file is ``.
+ *
+ * We highly recommend using the third method whenever possible.
+ *
+ */
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /*#************************************************************************
+ *
+ * If you enable this configuration option, FreeType recognizes an
+ * environment variable called `FREETYPE_PROPERTIES`, which can be used to
+ * control the various font drivers and modules. The controllable
+ * properties are listed in the section @properties.
+ *
+ * You have to undefine this configuration option on platforms that lack
+ * the concept of environment variables (and thus don't have the `getenv`
+ * function), for example Windows CE.
+ *
+ * `FREETYPE_PROPERTIES` has the following syntax form (broken here into
+ * multiple lines for better readability).
+ *
+ * ```
+ *
+ * ':'
+ * '='
+ *
+ * ':'
+ * '='
+ * ...
+ * ```
+ *
+ * Example:
+ *
+ * ```
+ * FREETYPE_PROPERTIES=truetype:interpreter-version=35 \
+ * cff:no-stem-darkening=1
+ * ```
+ *
+ */
+#define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
+
+
+ /**************************************************************************
+ *
+ * Uncomment the line below if you want to activate LCD rendering
+ * technology similar to ClearType in this build of the library. This
+ * technology triples the resolution in the direction color subpixels. To
+ * mitigate color fringes inherent to this technology, you also need to
+ * explicitly set up LCD filtering.
+ *
+ * When this macro is not defined, FreeType offers alternative LCD
+ * rendering technology that produces excellent output.
+ */
+/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
+
+
+ /**************************************************************************
+ *
+ * Many compilers provide a non-ANSI 64-bit data type that can be used by
+ * FreeType to speed up some computations. However, this will create some
+ * problems when compiling the library in strict ANSI mode.
+ *
+ * For this reason, the use of 64-bit integers is normally disabled when
+ * the `__STDC__` macro is defined. You can however disable this by
+ * defining the macro `FT_CONFIG_OPTION_FORCE_INT64` here.
+ *
+ * For most compilers, this will only create compilation warnings when
+ * building the library.
+ *
+ * ObNote: The compiler-specific 64-bit integers are detected in the
+ * file `ftconfig.h` either statically or through the `configure`
+ * script on supported platforms.
+ */
+#undef FT_CONFIG_OPTION_FORCE_INT64
+
+
+ /**************************************************************************
+ *
+ * If this macro is defined, do not try to use an assembler version of
+ * performance-critical functions (e.g., @FT_MulFix). You should only do
+ * that to verify that the assembler function works properly, or to execute
+ * benchmark tests of the various implementations.
+ */
+/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */
+
+
+ /**************************************************************************
+ *
+ * If this macro is defined, try to use an inlined assembler version of the
+ * @FT_MulFix function, which is a 'hotspot' when loading and hinting
+ * glyphs, and which should be executed as fast as possible.
+ *
+ * Note that if your compiler or CPU is not supported, this will default to
+ * the standard and portable implementation found in `ftcalc.c`.
+ */
+#define FT_CONFIG_OPTION_INLINE_MULFIX
+
+
+ /**************************************************************************
+ *
+ * LZW-compressed file support.
+ *
+ * FreeType now handles font files that have been compressed with the
+ * `compress` program. This is mostly used to parse many of the PCF
+ * files that come with various X11 distributions. The implementation
+ * uses NetBSD's `zopen` to partially uncompress the file on the fly (see
+ * `src/lzw/ftgzip.c`).
+ *
+ * Define this macro if you want to enable this 'feature'.
+ */
+#define FT_CONFIG_OPTION_USE_LZW
+
+
+ /**************************************************************************
+ *
+ * Gzip-compressed file support.
+ *
+ * FreeType now handles font files that have been compressed with the
+ * `gzip` program. This is mostly used to parse many of the PCF files
+ * that come with XFree86. The implementation uses 'zlib' to partially
+ * uncompress the file on the fly (see `src/gzip/ftgzip.c`).
+ *
+ * Define this macro if you want to enable this 'feature'. See also the
+ * macro `FT_CONFIG_OPTION_SYSTEM_ZLIB` below.
+ */
+#define FT_CONFIG_OPTION_USE_ZLIB
+
+
+ /**************************************************************************
+ *
+ * ZLib library selection
+ *
+ * This macro is only used when `FT_CONFIG_OPTION_USE_ZLIB` is defined.
+ * It allows FreeType's 'ftgzip' component to link to the system's
+ * installation of the ZLib library. This is useful on systems like
+ * Unix or VMS where it generally is already available.
+ *
+ * If you let it undefined, the component will use its own copy of the
+ * zlib sources instead. These have been modified to be included
+ * directly within the component and **not** export external function
+ * names. This allows you to link any program with FreeType _and_ ZLib
+ * without linking conflicts.
+ *
+ * Do not `#undef` this macro here since the build system might define
+ * it for certain configurations only.
+ *
+ * If you use a build system like cmake or the `configure` script,
+ * options set by those programs have precedence, overwriting the value
+ * here with the configured one.
+ *
+ * If you use the GNU make build system directly (that is, without the
+ * `configure` script) and you define this macro, you also have to pass
+ * `SYSTEM_ZLIB=yes` as an argument to make.
+ */
+#define FT_CONFIG_OPTION_SYSTEM_ZLIB
+
+
+ /**************************************************************************
+ *
+ * Bzip2-compressed file support.
+ *
+ * FreeType now handles font files that have been compressed with the
+ * `bzip2` program. This is mostly used to parse many of the PCF files
+ * that come with XFree86. The implementation uses `libbz2` to partially
+ * uncompress the file on the fly (see `src/bzip2/ftbzip2.c`). Contrary
+ * to gzip, bzip2 currently is not included and need to use the system
+ * available bzip2 implementation.
+ *
+ * Define this macro if you want to enable this 'feature'.
+ *
+ * If you use a build system like cmake or the `configure` script,
+ * options set by those programs have precedence, overwriting the value
+ * here with the configured one.
+ */
+/* #define FT_CONFIG_OPTION_USE_BZIP2 */
+
+
+ /**************************************************************************
+ *
+ * Define to disable the use of file stream functions and types, `FILE`,
+ * `fopen`, etc. Enables the use of smaller system libraries on embedded
+ * systems that have multiple system libraries, some with or without file
+ * stream support, in the cases where file stream support is not necessary
+ * such as memory loading of font files.
+ */
+/* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */
+
+
+ /**************************************************************************
+ *
+ * PNG bitmap support.
+ *
+ * FreeType now handles loading color bitmap glyphs in the PNG format.
+ * This requires help from the external libpng library. Uncompressed
+ * color bitmaps do not need any external libraries and will be supported
+ * regardless of this configuration.
+ *
+ * Define this macro if you want to enable this 'feature'.
+ *
+ * If you use a build system like cmake or the `configure` script,
+ * options set by those programs have precedence, overwriting the value
+ * here with the configured one.
+ */
+#define FT_CONFIG_OPTION_USE_PNG
+
+
+ /**************************************************************************
+ *
+ * HarfBuzz support.
+ *
+ * FreeType uses the HarfBuzz library to improve auto-hinting of OpenType
+ * fonts. If available, many glyphs not directly addressable by a font's
+ * character map will be hinted also.
+ *
+ * Define this macro if you want to enable this 'feature'.
+ *
+ * If you use a build system like cmake or the `configure` script,
+ * options set by those programs have precedence, overwriting the value
+ * here with the configured one.
+ */
+#define FT_CONFIG_OPTION_USE_HARFBUZZ
+
+
+ /**************************************************************************
+ *
+ * Brotli support.
+ *
+ * FreeType uses the Brotli library to provide support for decompressing
+ * WOFF2 streams.
+ *
+ * Define this macro if you want to enable this 'feature'.
+ *
+ * If you use a build system like cmake or the `configure` script,
+ * options set by those programs have precedence, overwriting the value
+ * here with the configured one.
+ */
+/* #define FT_CONFIG_OPTION_USE_BROTLI */
+
+
+ /**************************************************************************
+ *
+ * Glyph Postscript Names handling
+ *
+ * By default, FreeType 2 is compiled with the 'psnames' module. This
+ * module is in charge of converting a glyph name string into a Unicode
+ * value, or return a Macintosh standard glyph name for the use with the
+ * TrueType 'post' table.
+ *
+ * Undefine this macro if you do not want 'psnames' compiled in your
+ * build of FreeType. This has the following effects:
+ *
+ * - The TrueType driver will provide its own set of glyph names, if you
+ * build it to support postscript names in the TrueType 'post' table,
+ * but will not synthesize a missing Unicode charmap.
+ *
+ * - The Type~1 driver will not be able to synthesize a Unicode charmap
+ * out of the glyphs found in the fonts.
+ *
+ * You would normally undefine this configuration macro when building a
+ * version of FreeType that doesn't contain a Type~1 or CFF driver.
+ */
+#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES
+
+
+ /**************************************************************************
+ *
+ * Postscript Names to Unicode Values support
+ *
+ * By default, FreeType~2 is built with the 'psnames' module compiled in.
+ * Among other things, the module is used to convert a glyph name into a
+ * Unicode value. This is especially useful in order to synthesize on
+ * the fly a Unicode charmap from the CFF/Type~1 driver through a big
+ * table named the 'Adobe Glyph List' (AGL).
+ *
+ * Undefine this macro if you do not want the Adobe Glyph List compiled
+ * in your 'psnames' module. The Type~1 driver will not be able to
+ * synthesize a Unicode charmap out of the glyphs found in the fonts.
+ */
+#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
+
+
+ /**************************************************************************
+ *
+ * Support for Mac fonts
+ *
+ * Define this macro if you want support for outline fonts in Mac format
+ * (mac dfont, mac resource, macbinary containing a mac resource) on
+ * non-Mac platforms.
+ *
+ * Note that the 'FOND' resource isn't checked.
+ */
+#define FT_CONFIG_OPTION_MAC_FONTS
+
+
+ /**************************************************************************
+ *
+ * Guessing methods to access embedded resource forks
+ *
+ * Enable extra Mac fonts support on non-Mac platforms (e.g., GNU/Linux).
+ *
+ * Resource forks which include fonts data are stored sometimes in
+ * locations which users or developers don't expected. In some cases,
+ * resource forks start with some offset from the head of a file. In
+ * other cases, the actual resource fork is stored in file different from
+ * what the user specifies. If this option is activated, FreeType tries
+ * to guess whether such offsets or different file names must be used.
+ *
+ * Note that normal, direct access of resource forks is controlled via
+ * the `FT_CONFIG_OPTION_MAC_FONTS` option.
+ */
+#ifdef FT_CONFIG_OPTION_MAC_FONTS
+#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
+#endif
+
+
+ /**************************************************************************
+ *
+ * Allow the use of `FT_Incremental_Interface` to load typefaces that
+ * contain no glyph data, but supply it via a callback function. This is
+ * required by clients supporting document formats which supply font data
+ * incrementally as the document is parsed, such as the Ghostscript
+ * interpreter for the PostScript language.
+ */
+#define FT_CONFIG_OPTION_INCREMENTAL
+
+
+ /**************************************************************************
+ *
+ * The size in bytes of the render pool used by the scan-line converter to
+ * do all of its work.
+ */
+#define FT_RENDER_POOL_SIZE 16384L
+
+
+ /**************************************************************************
+ *
+ * FT_MAX_MODULES
+ *
+ * The maximum number of modules that can be registered in a single
+ * FreeType library object. 32~is the default.
+ */
+#define FT_MAX_MODULES 32
+
+
+ /**************************************************************************
+ *
+ * Debug level
+ *
+ * FreeType can be compiled in debug or trace mode. In debug mode,
+ * errors are reported through the 'ftdebug' component. In trace mode,
+ * additional messages are sent to the standard output during execution.
+ *
+ * Define `FT_DEBUG_LEVEL_ERROR` to build the library in debug mode.
+ * Define `FT_DEBUG_LEVEL_TRACE` to build it in trace mode.
+ *
+ * Don't define any of these macros to compile in 'release' mode!
+ *
+ * Do not `#undef` these macros here since the build system might define
+ * them for certain configurations only.
+ */
+/* #define FT_DEBUG_LEVEL_ERROR */
+/* #define FT_DEBUG_LEVEL_TRACE */
+
+
+ /**************************************************************************
+ *
+ * Logging
+ *
+ * Compiling FreeType in debug or trace mode makes FreeType write error
+ * and trace log messages to `stderr`. Enabling this macro
+ * automatically forces the `FT_DEBUG_LEVEL_ERROR` and
+ * `FT_DEBUG_LEVEL_TRACE` macros and allows FreeType to write error and
+ * trace log messages to a file instead of `stderr`. For writing logs
+ * to a file, FreeType uses an the external `dlg` library (the source
+ * code is in `src/dlg`).
+ *
+ * This option needs a C99 compiler.
+ */
+/* #define FT_DEBUG_LOGGING */
+
+
+ /**************************************************************************
+ *
+ * Autofitter debugging
+ *
+ * If `FT_DEBUG_AUTOFIT` is defined, FreeType provides some means to
+ * control the autofitter behaviour for debugging purposes with global
+ * boolean variables (consequently, you should **never** enable this
+ * while compiling in 'release' mode):
+ *
+ * ```
+ * _af_debug_disable_horz_hints
+ * _af_debug_disable_vert_hints
+ * _af_debug_disable_blue_hints
+ * ```
+ *
+ * Additionally, the following functions provide dumps of various
+ * internal autofit structures to stdout (using `printf`):
+ *
+ * ```
+ * af_glyph_hints_dump_points
+ * af_glyph_hints_dump_segments
+ * af_glyph_hints_dump_edges
+ * af_glyph_hints_get_num_segments
+ * af_glyph_hints_get_segment_offset
+ * ```
+ *
+ * As an argument, they use another global variable:
+ *
+ * ```
+ * _af_debug_hints
+ * ```
+ *
+ * Please have a look at the `ftgrid` demo program to see how those
+ * variables and macros should be used.
+ *
+ * Do not `#undef` these macros here since the build system might define
+ * them for certain configurations only.
+ */
+/* #define FT_DEBUG_AUTOFIT */
+
+
+ /**************************************************************************
+ *
+ * Memory Debugging
+ *
+ * FreeType now comes with an integrated memory debugger that is capable
+ * of detecting simple errors like memory leaks or double deletes. To
+ * compile it within your build of the library, you should define
+ * `FT_DEBUG_MEMORY` here.
+ *
+ * Note that the memory debugger is only activated at runtime when when
+ * the _environment_ variable `FT2_DEBUG_MEMORY` is defined also!
+ *
+ * Do not `#undef` this macro here since the build system might define it
+ * for certain configurations only.
+ */
+/* #define FT_DEBUG_MEMORY */
+
+
+ /**************************************************************************
+ *
+ * Module errors
+ *
+ * If this macro is set (which is _not_ the default), the higher byte of
+ * an error code gives the module in which the error has occurred, while
+ * the lower byte is the real error code.
+ *
+ * Setting this macro makes sense for debugging purposes only, since it
+ * would break source compatibility of certain programs that use
+ * FreeType~2.
+ *
+ * More details can be found in the files `ftmoderr.h` and `fterrors.h`.
+ */
+#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS
+
+
+ /**************************************************************************
+ *
+ * OpenType SVG Glyph Support
+ *
+ * Setting this macro enables support for OpenType SVG glyphs. By
+ * default, FreeType can only fetch SVG documents. However, it can also
+ * render them if external rendering hook functions are plugged in at
+ * runtime.
+ *
+ * More details on the hooks can be found in file `otsvg.h`.
+ */
+#define FT_CONFIG_OPTION_SVG
+
+
+ /**************************************************************************
+ *
+ * Error Strings
+ *
+ * If this macro is set, `FT_Error_String` will return meaningful
+ * descriptions. This is not enabled by default to reduce the overall
+ * size of FreeType.
+ *
+ * More details can be found in the file `fterrors.h`.
+ */
+/* #define FT_CONFIG_OPTION_ERROR_STRINGS */
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** S F N T D R I V E R C O N F I G U R A T I O N ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /**************************************************************************
+ *
+ * Define `TT_CONFIG_OPTION_EMBEDDED_BITMAPS` if you want to support
+ * embedded bitmaps in all formats using the 'sfnt' module (namely
+ * TrueType~& OpenType).
+ */
+#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+
+
+ /**************************************************************************
+ *
+ * Define `TT_CONFIG_OPTION_COLOR_LAYERS` if you want to support colored
+ * outlines (from the 'COLR'/'CPAL' tables) in all formats using the 'sfnt'
+ * module (namely TrueType~& OpenType).
+ */
+#define TT_CONFIG_OPTION_COLOR_LAYERS
+
+
+ /**************************************************************************
+ *
+ * Define `TT_CONFIG_OPTION_POSTSCRIPT_NAMES` if you want to be able to
+ * load and enumerate the glyph Postscript names in a TrueType or OpenType
+ * file.
+ *
+ * Note that when you do not compile the 'psnames' module by undefining the
+ * above `FT_CONFIG_OPTION_POSTSCRIPT_NAMES`, the 'sfnt' module will
+ * contain additional code used to read the PS Names table from a font.
+ *
+ * (By default, the module uses 'psnames' to extract glyph names.)
+ */
+#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+
+
+ /**************************************************************************
+ *
+ * Define `TT_CONFIG_OPTION_SFNT_NAMES` if your applications need to access
+ * the internal name table in a SFNT-based format like TrueType or
+ * OpenType. The name table contains various strings used to describe the
+ * font, like family name, copyright, version, etc. It does not contain
+ * any glyph name though.
+ *
+ * Accessing SFNT names is done through the functions declared in
+ * `ftsnames.h`.
+ */
+#define TT_CONFIG_OPTION_SFNT_NAMES
+
+
+ /**************************************************************************
+ *
+ * TrueType CMap support
+ *
+ * Here you can fine-tune which TrueType CMap table format shall be
+ * supported.
+ */
+#define TT_CONFIG_CMAP_FORMAT_0
+#define TT_CONFIG_CMAP_FORMAT_2
+#define TT_CONFIG_CMAP_FORMAT_4
+#define TT_CONFIG_CMAP_FORMAT_6
+#define TT_CONFIG_CMAP_FORMAT_8
+#define TT_CONFIG_CMAP_FORMAT_10
+#define TT_CONFIG_CMAP_FORMAT_12
+#define TT_CONFIG_CMAP_FORMAT_13
+#define TT_CONFIG_CMAP_FORMAT_14
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /**************************************************************************
+ *
+ * Define `TT_CONFIG_OPTION_BYTECODE_INTERPRETER` if you want to compile a
+ * bytecode interpreter in the TrueType driver.
+ *
+ * By undefining this, you will only compile the code necessary to load
+ * TrueType glyphs without hinting.
+ *
+ * Do not `#undef` this macro here, since the build system might define it
+ * for certain configurations only.
+ */
+#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+
+
+ /**************************************************************************
+ *
+ * Define `TT_CONFIG_OPTION_SUBPIXEL_HINTING` if you want to compile
+ * subpixel hinting support into the TrueType driver. This modifies the
+ * TrueType hinting mechanism when anything but `FT_RENDER_MODE_MONO` is
+ * requested.
+ *
+ * In particular, it modifies the bytecode interpreter to interpret (or
+ * not) instructions in a certain way so that all TrueType fonts look like
+ * they do in a Windows ClearType (DirectWrite) environment. See [1] for a
+ * technical overview on what this means. See `ttinterp.h` for more
+ * details on the LEAN option.
+ *
+ * There are three possible values.
+ *
+ * Value 1:
+ * This value is associated with the 'Infinality' moniker, contributed by
+ * an individual nicknamed Infinality with the goal of making TrueType
+ * fonts render better than on Windows. A high amount of configurability
+ * and flexibility, down to rules for single glyphs in fonts, but also
+ * very slow. Its experimental and slow nature and the original
+ * developer losing interest meant that this option was never enabled in
+ * default builds.
+ *
+ * The corresponding interpreter version is v38.
+ *
+ * Value 2:
+ * The new default mode for the TrueType driver. The Infinality code
+ * base was stripped to the bare minimum and all configurability removed
+ * in the name of speed and simplicity. The configurability was mainly
+ * aimed at legacy fonts like 'Arial', 'Times New Roman', or 'Courier'.
+ * Legacy fonts are fonts that modify vertical stems to achieve clean
+ * black-and-white bitmaps. The new mode focuses on applying a minimal
+ * set of rules to all fonts indiscriminately so that modern and web
+ * fonts render well while legacy fonts render okay.
+ *
+ * The corresponding interpreter version is v40.
+ *
+ * Value 3:
+ * Compile both, making both v38 and v40 available (the latter is the
+ * default).
+ *
+ * By undefining these, you get rendering behavior like on Windows without
+ * ClearType, i.e., Windows XP without ClearType enabled and Win9x
+ * (interpreter version v35). Or not, depending on how much hinting blood
+ * and testing tears the font designer put into a given font. If you
+ * define one or both subpixel hinting options, you can switch between
+ * between v35 and the ones you define (using `FT_Property_Set`).
+ *
+ * This option requires `TT_CONFIG_OPTION_BYTECODE_INTERPRETER` to be
+ * defined.
+ *
+ * [1]
+ * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
+ */
+/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */
+#define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2
+/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */
+
+
+ /**************************************************************************
+ *
+ * Define `TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED` to compile the
+ * TrueType glyph loader to use Apple's definition of how to handle
+ * component offsets in composite glyphs.
+ *
+ * Apple and MS disagree on the default behavior of component offsets in
+ * composites. Apple says that they should be scaled by the scaling
+ * factors in the transformation matrix (roughly, it's more complex) while
+ * MS says they should not. OpenType defines two bits in the composite
+ * flags array which can be used to disambiguate, but old fonts will not
+ * have them.
+ *
+ * https://www.microsoft.com/typography/otspec/glyf.htm
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html
+ */
+#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
+
+
+ /**************************************************************************
+ *
+ * Define `TT_CONFIG_OPTION_GX_VAR_SUPPORT` if you want to include support
+ * for Apple's distortable font technology ('fvar', 'gvar', 'cvar', and
+ * 'avar' tables). Tagged 'Font Variations', this is now part of OpenType
+ * also. This has many similarities to Type~1 Multiple Masters support.
+ */
+#define TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
+
+ /**************************************************************************
+ *
+ * Define `TT_CONFIG_OPTION_BDF` if you want to include support for an
+ * embedded 'BDF~' table within SFNT-based bitmap formats.
+ */
+#define TT_CONFIG_OPTION_BDF
+
+
+ /**************************************************************************
+ *
+ * Option `TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES` controls the maximum
+ * number of bytecode instructions executed for a single run of the
+ * bytecode interpreter, needed to prevent infinite loops. You don't want
+ * to change this except for very special situations (e.g., making a
+ * library fuzzer spend less time to handle broken fonts).
+ *
+ * It is not expected that this value is ever modified by a configuring
+ * script; instead, it gets surrounded with `#ifndef ... #endif` so that
+ * the value can be set as a preprocessor option on the compiler's command
+ * line.
+ */
+#ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES
+#define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES 1000000L
+#endif
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /**************************************************************************
+ *
+ * `T1_MAX_DICT_DEPTH` is the maximum depth of nest dictionaries and arrays
+ * in the Type~1 stream (see `t1load.c`). A minimum of~4 is required.
+ */
+#define T1_MAX_DICT_DEPTH 5
+
+
+ /**************************************************************************
+ *
+ * `T1_MAX_SUBRS_CALLS` details the maximum number of nested sub-routine
+ * calls during glyph loading.
+ */
+#define T1_MAX_SUBRS_CALLS 16
+
+
+ /**************************************************************************
+ *
+ * `T1_MAX_CHARSTRING_OPERANDS` is the charstring stack's capacity. A
+ * minimum of~16 is required.
+ *
+ * The Chinese font 'MingTiEG-Medium' (covering the CNS 11643 character
+ * set) needs 256.
+ */
+#define T1_MAX_CHARSTRINGS_OPERANDS 256
+
+
+ /**************************************************************************
+ *
+ * Define this configuration macro if you want to prevent the compilation
+ * of the 't1afm' module, which is in charge of reading Type~1 AFM files
+ * into an existing face. Note that if set, the Type~1 driver will be
+ * unable to produce kerning distances.
+ */
+#undef T1_CONFIG_OPTION_NO_AFM
+
+
+ /**************************************************************************
+ *
+ * Define this configuration macro if you want to prevent the compilation
+ * of the Multiple Masters font support in the Type~1 driver.
+ */
+#undef T1_CONFIG_OPTION_NO_MM_SUPPORT
+
+
+ /**************************************************************************
+ *
+ * `T1_CONFIG_OPTION_OLD_ENGINE` controls whether the pre-Adobe Type~1
+ * engine gets compiled into FreeType. If defined, it is possible to
+ * switch between the two engines using the `hinting-engine` property of
+ * the 'type1' driver module.
+ */
+/* #define T1_CONFIG_OPTION_OLD_ENGINE */
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** C F F D R I V E R C O N F I G U R A T I O N ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /**************************************************************************
+ *
+ * Using `CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4}` it is
+ * possible to set up the default values of the four control points that
+ * define the stem darkening behaviour of the (new) CFF engine. For more
+ * details please read the documentation of the `darkening-parameters`
+ * property (file `ftdriver.h`), which allows the control at run-time.
+ *
+ * Do **not** undefine these macros!
+ */
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 500
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 400
+
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 1000
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 275
+
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 1667
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 275
+
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 2333
+#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 0
+
+
+ /**************************************************************************
+ *
+ * `CFF_CONFIG_OPTION_OLD_ENGINE` controls whether the pre-Adobe CFF engine
+ * gets compiled into FreeType. If defined, it is possible to switch
+ * between the two engines using the `hinting-engine` property of the 'cff'
+ * driver module.
+ */
+/* #define CFF_CONFIG_OPTION_OLD_ENGINE */
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** P C F D R I V E R C O N F I G U R A T I O N ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /**************************************************************************
+ *
+ * There are many PCF fonts just called 'Fixed' which look completely
+ * different, and which have nothing to do with each other. When selecting
+ * 'Fixed' in KDE or Gnome one gets results that appear rather random, the
+ * style changes often if one changes the size and one cannot select some
+ * fonts at all. This option makes the 'pcf' module prepend the foundry
+ * name (plus a space) to the family name.
+ *
+ * We also check whether we have 'wide' characters; all put together, we
+ * get family names like 'Sony Fixed' or 'Misc Fixed Wide'.
+ *
+ * If this option is activated, it can be controlled with the
+ * `no-long-family-names` property of the 'pcf' driver module.
+ */
+/* #define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /**** ****/
+ /**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/
+ /**** ****/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /**************************************************************************
+ *
+ * Compile 'autofit' module with CJK (Chinese, Japanese, Korean) script
+ * support.
+ */
+#define AF_CONFIG_OPTION_CJK
+
+
+ /**************************************************************************
+ *
+ * Compile 'autofit' module with fallback Indic script support, covering
+ * some scripts that the 'latin' submodule of the 'autofit' module doesn't
+ * (yet) handle. Currently, this needs option `AF_CONFIG_OPTION_CJK`.
+ */
+#ifdef AF_CONFIG_OPTION_CJK
+#define AF_CONFIG_OPTION_INDIC
+#endif
+
+
+ /**************************************************************************
+ *
+ * Use TrueType-like size metrics for 'light' auto-hinting.
+ *
+ * It is strongly recommended to avoid this option, which exists only to
+ * help some legacy applications retain its appearance and behaviour with
+ * respect to auto-hinted TrueType fonts.
+ *
+ * The very reason this option exists at all are GNU/Linux distributions
+ * like Fedora that did not un-patch the following change (which was
+ * present in FreeType between versions 2.4.6 and 2.7.1, inclusive).
+ *
+ * ```
+ * 2011-07-16 Steven Chu
+ *
+ * [truetype] Fix metrics on size request for scalable fonts.
+ * ```
+ *
+ * This problematic commit is now reverted (more or less).
+ */
+/* #define AF_CONFIG_OPTION_TT_SIZE_METRICS */
+
+ /* */
+
+
+ /*
+ * This macro is obsolete. Support has been removed in FreeType version
+ * 2.5.
+ */
+/* #define FT_CONFIG_OPTION_OLD_INTERNALS */
+
+
+ /*
+ * The next three macros are defined if native TrueType hinting is
+ * requested by the definitions above. Don't change this.
+ */
+#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+#define TT_USE_BYTECODE_INTERPRETER
+
+#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
+#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1
+#define TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
+#endif
+
+#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2
+#define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+#endif
+#endif
+#endif
+
+
+ /*
+ * The TT_SUPPORT_COLRV1 macro is defined to indicate to clients that this
+ * version of FreeType has support for 'COLR' v1 API. This definition is
+ * useful to FreeType clients that want to build in support for 'COLR' v1
+ * depending on a tip-of-tree checkout before it is officially released in
+ * FreeType, and while the feature cannot yet be tested against using
+ * version macros. Don't change this macro. This may be removed once the
+ * feature is in a FreeType release version and version macros can be used
+ * to test for availability.
+ */
+#ifdef TT_CONFIG_OPTION_COLOR_LAYERS
+#define TT_SUPPORT_COLRV1
+#endif
+
+
+ /*
+ * Check CFF darkening parameters. The checks are the same as in function
+ * `cff_property_set` in file `cffdrivr.c`.
+ */
+#if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0 || \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0 || \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 < 0 || \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 < 0 || \
+ \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 < 0 || \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 < 0 || \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 < 0 || \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 < 0 || \
+ \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 > \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 || \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 > \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 || \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 > \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 || \
+ \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 > 500 || \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 > 500 || \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 > 500 || \
+ CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 > 500
+#error "Invalid CFF darkening parameters!"
+#endif
+
+
+FT_END_HEADER
+
+#endif /* FTOPTION_H_ */
+
+
+/* END */
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftstdlib.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftstdlib.h
new file mode 100644
index 0000000..7958c2a
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/ftstdlib.h
@@ -0,0 +1,185 @@
+/****************************************************************************
+ *
+ * ftstdlib.h
+ *
+ * ANSI-specific library and header configuration file (specification
+ * only).
+ *
+ * Copyright (C) 2002-2022 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+ /**************************************************************************
+ *
+ * This file is used to group all `#includes` to the ANSI~C library that
+ * FreeType normally requires. It also defines macros to rename the
+ * standard functions within the FreeType source code.
+ *
+ * Load a file which defines `FTSTDLIB_H_` before this one to override it.
+ *
+ */
+
+
+#ifndef FTSTDLIB_H_
+#define FTSTDLIB_H_
+
+
+#include
+
+#define ft_ptrdiff_t ptrdiff_t
+
+
+ /**************************************************************************
+ *
+ * integer limits
+ *
+ * `UINT_MAX` and `ULONG_MAX` are used to automatically compute the size of
+ * `int` and `long` in bytes at compile-time. So far, this works for all
+ * platforms the library has been tested on. We also check `ULLONG_MAX`
+ * to see whether we can use 64-bit `long long` later on.
+ *
+ * Note that on the extremely rare platforms that do not provide integer
+ * types that are _exactly_ 16 and 32~bits wide (e.g., some old Crays where
+ * `int` is 36~bits), we do not make any guarantee about the correct
+ * behaviour of FreeType~2 with all fonts.
+ *
+ * In these cases, `ftconfig.h` will refuse to compile anyway with a
+ * message like 'couldn't find 32-bit type' or something similar.
+ *
+ */
+
+
+#include
+
+#define FT_CHAR_BIT CHAR_BIT
+#define FT_USHORT_MAX USHRT_MAX
+#define FT_INT_MAX INT_MAX
+#define FT_INT_MIN INT_MIN
+#define FT_UINT_MAX UINT_MAX
+#define FT_LONG_MIN LONG_MIN
+#define FT_LONG_MAX LONG_MAX
+#define FT_ULONG_MAX ULONG_MAX
+#ifdef LLONG_MAX
+#define FT_LLONG_MAX LLONG_MAX
+#endif
+#ifdef LLONG_MIN
+#define FT_LLONG_MIN LLONG_MIN
+#endif
+#ifdef ULLONG_MAX
+#define FT_ULLONG_MAX ULLONG_MAX
+#endif
+
+
+ /**************************************************************************
+ *
+ * character and string processing
+ *
+ */
+
+
+#include
+
+#define ft_memchr memchr
+#define ft_memcmp memcmp
+#define ft_memcpy memcpy
+#define ft_memmove memmove
+#define ft_memset memset
+#define ft_strcat strcat
+#define ft_strcmp strcmp
+#define ft_strcpy strcpy
+#define ft_strlen strlen
+#define ft_strncmp strncmp
+#define ft_strncpy strncpy
+#define ft_strrchr strrchr
+#define ft_strstr strstr
+
+
+ /**************************************************************************
+ *
+ * file handling
+ *
+ */
+
+
+#include
+
+#define FT_FILE FILE
+#define ft_fclose fclose
+#define ft_fopen fopen
+#define ft_fread fread
+#define ft_fseek fseek
+#define ft_ftell ftell
+#define ft_sprintf sprintf
+
+
+ /**************************************************************************
+ *
+ * sorting
+ *
+ */
+
+
+#include
+
+#define ft_qsort qsort
+
+
+ /**************************************************************************
+ *
+ * memory allocation
+ *
+ */
+
+
+#define ft_scalloc calloc
+#define ft_sfree free
+#define ft_smalloc malloc
+#define ft_srealloc realloc
+
+
+ /**************************************************************************
+ *
+ * miscellaneous
+ *
+ */
+
+
+#define ft_strtol strtol
+#define ft_getenv getenv
+
+
+ /**************************************************************************
+ *
+ * execution control
+ *
+ */
+
+
+#include
+
+#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */
+ /* `jmp_buf` is defined as a macro */
+ /* on certain platforms */
+
+#define ft_longjmp longjmp
+#define ft_setjmp( b ) setjmp( *(ft_jmp_buf*) &(b) ) /* same thing here */
+
+
+ /* The following is only used for debugging purposes, i.e., if */
+ /* `FT_DEBUG_LEVEL_ERROR` or `FT_DEBUG_LEVEL_TRACE` are defined. */
+
+#include
+
+
+#endif /* FTSTDLIB_H_ */
+
+
+/* END */
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/integer-types.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/integer-types.h
new file mode 100644
index 0000000..d9d2638
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/integer-types.h
@@ -0,0 +1,250 @@
+/****************************************************************************
+ *
+ * config/integer-types.h
+ *
+ * FreeType integer types definitions.
+ *
+ * Copyright (C) 1996-2022 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+#ifndef FREETYPE_CONFIG_INTEGER_TYPES_H_
+#define FREETYPE_CONFIG_INTEGER_TYPES_H_
+
+ /* There are systems (like the Texas Instruments 'C54x) where a `char` */
+ /* has 16~bits. ANSI~C says that `sizeof(char)` is always~1. Since an */
+ /* `int` has 16~bits also for this system, `sizeof(int)` gives~1 which */
+ /* is probably unexpected. */
+ /* */
+ /* `CHAR_BIT` (defined in `limits.h`) gives the number of bits in a */
+ /* `char` type. */
+
+#ifndef FT_CHAR_BIT
+#define FT_CHAR_BIT CHAR_BIT
+#endif
+
+#ifndef FT_SIZEOF_INT
+
+ /* The size of an `int` type. */
+#if FT_UINT_MAX == 0xFFFFUL
+#define FT_SIZEOF_INT ( 16 / FT_CHAR_BIT )
+#elif FT_UINT_MAX == 0xFFFFFFFFUL
+#define FT_SIZEOF_INT ( 32 / FT_CHAR_BIT )
+#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL
+#define FT_SIZEOF_INT ( 64 / FT_CHAR_BIT )
+#else
+#error "Unsupported size of `int' type!"
+#endif
+
+#endif /* !defined(FT_SIZEOF_INT) */
+
+#ifndef FT_SIZEOF_LONG
+
+ /* The size of a `long` type. A five-byte `long` (as used e.g. on the */
+ /* DM642) is recognized but avoided. */
+#if FT_ULONG_MAX == 0xFFFFFFFFUL
+#define FT_SIZEOF_LONG ( 32 / FT_CHAR_BIT )
+#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL
+#define FT_SIZEOF_LONG ( 32 / FT_CHAR_BIT )
+#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL
+#define FT_SIZEOF_LONG ( 64 / FT_CHAR_BIT )
+#else
+#error "Unsupported size of `long' type!"
+#endif
+
+#endif /* !defined(FT_SIZEOF_LONG) */
+
+#ifndef FT_SIZEOF_LONG_LONG
+
+ /* The size of a `long long` type if available */
+#if defined( FT_ULLONG_MAX ) && FT_ULLONG_MAX >= 0xFFFFFFFFFFFFFFFFULL
+#define FT_SIZEOF_LONG_LONG ( 64 / FT_CHAR_BIT )
+#else
+#define FT_SIZEOF_LONG_LONG 0
+#endif
+
+#endif /* !defined(FT_SIZEOF_LONG_LONG) */
+
+
+ /**************************************************************************
+ *
+ * @section:
+ * basic_types
+ *
+ */
+
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_Int16
+ *
+ * @description:
+ * A typedef for a 16bit signed integer type.
+ */
+ typedef signed short FT_Int16;
+
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_UInt16
+ *
+ * @description:
+ * A typedef for a 16bit unsigned integer type.
+ */
+ typedef unsigned short FT_UInt16;
+
+ /* */
+
+
+ /* this #if 0 ... #endif clause is for documentation purposes */
+#if 0
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_Int32
+ *
+ * @description:
+ * A typedef for a 32bit signed integer type. The size depends on the
+ * configuration.
+ */
+ typedef signed XXX FT_Int32;
+
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_UInt32
+ *
+ * A typedef for a 32bit unsigned integer type. The size depends on the
+ * configuration.
+ */
+ typedef unsigned XXX FT_UInt32;
+
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_Int64
+ *
+ * A typedef for a 64bit signed integer type. The size depends on the
+ * configuration. Only defined if there is real 64bit support;
+ * otherwise, it gets emulated with a structure (if necessary).
+ */
+ typedef signed XXX FT_Int64;
+
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_UInt64
+ *
+ * A typedef for a 64bit unsigned integer type. The size depends on the
+ * configuration. Only defined if there is real 64bit support;
+ * otherwise, it gets emulated with a structure (if necessary).
+ */
+ typedef unsigned XXX FT_UInt64;
+
+ /* */
+
+#endif
+
+#if FT_SIZEOF_INT == ( 32 / FT_CHAR_BIT )
+
+ typedef signed int FT_Int32;
+ typedef unsigned int FT_UInt32;
+
+#elif FT_SIZEOF_LONG == ( 32 / FT_CHAR_BIT )
+
+ typedef signed long FT_Int32;
+ typedef unsigned long FT_UInt32;
+
+#else
+#error "no 32bit type found -- please check your configuration files"
+#endif
+
+
+ /* look up an integer type that is at least 32~bits */
+#if FT_SIZEOF_INT >= ( 32 / FT_CHAR_BIT )
+
+ typedef int FT_Fast;
+ typedef unsigned int FT_UFast;
+
+#elif FT_SIZEOF_LONG >= ( 32 / FT_CHAR_BIT )
+
+ typedef long FT_Fast;
+ typedef unsigned long FT_UFast;
+
+#endif
+
+
+ /* determine whether we have a 64-bit integer type */
+#if FT_SIZEOF_LONG == ( 64 / FT_CHAR_BIT )
+
+#define FT_INT64 long
+#define FT_UINT64 unsigned long
+
+#elif FT_SIZEOF_LONG_LONG >= ( 64 / FT_CHAR_BIT )
+
+#define FT_INT64 long long int
+#define FT_UINT64 unsigned long long int
+
+ /**************************************************************************
+ *
+ * A 64-bit data type may create compilation problems if you compile in
+ * strict ANSI mode. To avoid them, we disable other 64-bit data types if
+ * `__STDC__` is defined. You can however ignore this rule by defining the
+ * `FT_CONFIG_OPTION_FORCE_INT64` configuration macro.
+ */
+#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 )
+
+#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */
+
+ /* this compiler provides the `__int64` type */
+#define FT_INT64 __int64
+#define FT_UINT64 unsigned __int64
+
+#elif defined( __BORLANDC__ ) /* Borland C++ */
+
+ /* XXXX: We should probably check the value of `__BORLANDC__` in order */
+ /* to test the compiler version. */
+
+ /* this compiler provides the `__int64` type */
+#define FT_INT64 __int64
+#define FT_UINT64 unsigned __int64
+
+#elif defined( __WATCOMC__ ) && __WATCOMC__ >= 1100 /* Watcom C++ */
+
+#define FT_INT64 long long int
+#define FT_UINT64 unsigned long long int
+
+#elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */
+
+#define FT_INT64 long long int
+#define FT_UINT64 unsigned long long int
+
+#elif defined( __GNUC__ )
+
+ /* GCC provides the `long long` type */
+#define FT_INT64 long long int
+#define FT_UINT64 unsigned long long int
+
+#endif /* !__STDC__ */
+
+#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
+
+#ifdef FT_INT64
+ typedef FT_INT64 FT_Int64;
+ typedef FT_UINT64 FT_UInt64;
+#endif
+
+
+#endif /* FREETYPE_CONFIG_INTEGER_TYPES_H_ */
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/mac-support.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/mac-support.h
new file mode 100644
index 0000000..e42c9fe
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/mac-support.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ *
+ * config/mac-support.h
+ *
+ * Mac/OS X support configuration header.
+ *
+ * Copyright (C) 1996-2022 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+#ifndef FREETYPE_CONFIG_MAC_SUPPORT_H_
+#define FREETYPE_CONFIG_MAC_SUPPORT_H_
+
+ /**************************************************************************
+ *
+ * Mac support
+ *
+ * This is the only necessary change, so it is defined here instead
+ * providing a new configuration file.
+ */
+#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) )
+ /* No Carbon frameworks for 64bit 10.4.x. */
+ /* `AvailabilityMacros.h` is available since Mac OS X 10.2, */
+ /* so guess the system version by maximum errno before inclusion. */
+#include
+#ifdef ECANCELED /* defined since 10.2 */
+#include "AvailabilityMacros.h"
+#endif
+#if defined( __LP64__ ) && \
+ ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 )
+#undef FT_MACINTOSH
+#endif
+
+#elif defined( __SC__ ) || defined( __MRC__ )
+ /* Classic MacOS compilers */
+#include "ConditionalMacros.h"
+#if TARGET_OS_MAC
+#define FT_MACINTOSH 1
+#endif
+
+#endif /* Mac support */
+
+#endif /* FREETYPE_CONFIG_MAC_SUPPORT_H_ */
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/public-macros.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/public-macros.h
new file mode 100644
index 0000000..0074134
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/config/public-macros.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+ *
+ * config/public-macros.h
+ *
+ * Define a set of compiler macros used in public FreeType headers.
+ *
+ * Copyright (C) 2020-2022 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+ /*
+ * The definitions in this file are used by the public FreeType headers
+ * and thus should be considered part of the public API.
+ *
+ * Other compiler-specific macro definitions that are not exposed by the
+ * FreeType API should go into
+ * `include/freetype/internal/compiler-macros.h` instead.
+ */
+#ifndef FREETYPE_CONFIG_PUBLIC_MACROS_H_
+#define FREETYPE_CONFIG_PUBLIC_MACROS_H_
+
+ /*
+ * `FT_BEGIN_HEADER` and `FT_END_HEADER` might have already been defined
+ * by `freetype/config/ftheader.h`, but we don't want to include this
+ * header here, so redefine the macros here only when needed. Their
+ * definition is very stable, so keeping them in sync with the ones in the
+ * header should not be a maintenance issue.
+ */
+#ifndef FT_BEGIN_HEADER
+#ifdef __cplusplus
+#define FT_BEGIN_HEADER extern "C" {
+#else
+#define FT_BEGIN_HEADER /* empty */
+#endif
+#endif /* FT_BEGIN_HEADER */
+
+#ifndef FT_END_HEADER
+#ifdef __cplusplus
+#define FT_END_HEADER }
+#else
+#define FT_END_HEADER /* empty */
+#endif
+#endif /* FT_END_HEADER */
+
+
+FT_BEGIN_HEADER
+
+ /*
+ * Mark a function declaration as public. This ensures it will be
+ * properly exported to client code. Place this before a function
+ * declaration.
+ *
+ * NOTE: This macro should be considered an internal implementation
+ * detail, and not part of the FreeType API. It is only defined here
+ * because it is needed by `FT_EXPORT`.
+ */
+
+ /* Visual C, mingw */
+#if defined( _WIN32 )
+
+#if defined( FT2_BUILD_LIBRARY ) && defined( DLL_EXPORT )
+#define FT_PUBLIC_FUNCTION_ATTRIBUTE __declspec( dllexport )
+#elif defined( DLL_IMPORT )
+#define FT_PUBLIC_FUNCTION_ATTRIBUTE __declspec( dllimport )
+#endif
+
+ /* gcc, clang */
+#elif ( defined( __GNUC__ ) && __GNUC__ >= 4 ) || defined( __clang__ )
+#define FT_PUBLIC_FUNCTION_ATTRIBUTE \
+ __attribute__(( visibility( "default" ) ))
+
+ /* Sun */
+#elif defined( __SUNPRO_C ) && __SUNPRO_C >= 0x550
+#define FT_PUBLIC_FUNCTION_ATTRIBUTE __global
+#endif
+
+
+#ifndef FT_PUBLIC_FUNCTION_ATTRIBUTE
+#define FT_PUBLIC_FUNCTION_ATTRIBUTE /* empty */
+#endif
+
+
+ /*
+ * Define a public FreeType API function. This ensures it is properly
+ * exported or imported at build time. The macro parameter is the
+ * function's return type as in:
+ *
+ * FT_EXPORT( FT_Bool )
+ * FT_Object_Method( FT_Object obj,
+ * ... );
+ *
+ * NOTE: This requires that all `FT_EXPORT` uses are inside
+ * `FT_BEGIN_HEADER ... FT_END_HEADER` blocks. This guarantees that the
+ * functions are exported with C linkage, even when the header is included
+ * by a C++ source file.
+ */
+#define FT_EXPORT( x ) FT_PUBLIC_FUNCTION_ATTRIBUTE extern x
+
+
+ /*
+ * `FT_UNUSED` indicates that a given parameter is not used -- this is
+ * only used to get rid of unpleasant compiler warnings.
+ *
+ * Technically, this was not meant to be part of the public API, but some
+ * third-party code depends on it.
+ */
+#ifndef FT_UNUSED
+#define FT_UNUSED( arg ) ( (arg) = (arg) )
+#endif
+
+
+ /*
+ * Support for casts in both C and C++.
+ */
+#ifdef __cplusplus
+#define FT_STATIC_CAST( type, var ) static_cast(var)
+#define FT_REINTERPRET_CAST( type, var ) reinterpret_cast(var)
+
+#define FT_STATIC_BYTE_CAST( type, var ) \
+ static_cast( static_cast( var ) )
+#else
+#define FT_STATIC_CAST( type, var ) (type)(var)
+#define FT_REINTERPRET_CAST( type, var ) (type)(var)
+
+#define FT_STATIC_BYTE_CAST( type, var ) (type)(unsigned char)(var)
+#endif
+
+
+FT_END_HEADER
+
+#endif /* FREETYPE_CONFIG_PUBLIC_MACROS_H_ */
diff --git a/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/freetype.h b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/freetype.h
new file mode 100644
index 0000000..aa1a4fe
--- /dev/null
+++ b/third_party/vips-dev-w64-web-8.13.3/vips-dev-8.13/include/freetype2/freetype/freetype.h
@@ -0,0 +1,5050 @@
+/****************************************************************************
+ *
+ * freetype.h
+ *
+ * FreeType high-level API and common types (specification only).
+ *
+ * Copyright (C) 1996-2022 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+#ifndef FREETYPE_H_
+#define FREETYPE_H_
+
+
+#include
+#include FT_CONFIG_CONFIG_H
+#include
+#include
+
+
+FT_BEGIN_HEADER
+
+
+
+ /**************************************************************************
+ *
+ * @section:
+ * preamble
+ *
+ * @title:
+ * Preamble
+ *
+ * @abstract:
+ * What FreeType is and isn't
+ *
+ * @description:
+ * FreeType is a library that provides access to glyphs in font files. It
+ * scales the glyph images and their metrics to a requested size, and it
+ * rasterizes the glyph images to produce pixel or subpixel alpha coverage
+ * bitmaps.
+ *
+ * Note that FreeType is _not_ a text layout engine. You have to use
+ * higher-level libraries like HarfBuzz, Pango, or ICU for that.
+ *
+ * Note also that FreeType does _not_ perform alpha blending or
+ * compositing the resulting bitmaps or pixmaps by itself. Use your
+ * favourite graphics library (for example, Cairo or Skia) to further
+ * process FreeType's output.
+ *
+ */
+
+
+ /**************************************************************************
+ *
+ * @section:
+ * header_inclusion
+ *
+ * @title:
+ * FreeType's header inclusion scheme
+ *
+ * @abstract:
+ * How client applications should include FreeType header files.
+ *
+ * @description:
+ * To be as flexible as possible (and for historical reasons), you must
+ * load file `ft2build.h` first before other header files, for example
+ *
+ * ```
+ * #include
+ *
+ * #include
+ * #include
+ * ```
+ */
+
+
+ /**************************************************************************
+ *
+ * @section:
+ * user_allocation
+ *
+ * @title:
+ * User allocation
+ *
+ * @abstract:
+ * How client applications should allocate FreeType data structures.
+ *
+ * @description:
+ * FreeType assumes that structures allocated by the user and passed as
+ * arguments are zeroed out except for the actual data. In other words,
+ * it is recommended to use `calloc` (or variants of it) instead of
+ * `malloc` for allocation.
+ *
+ */
+
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /* */
+ /* B A S I C T Y P E S */
+ /* */
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /**************************************************************************
+ *
+ * @section:
+ * base_interface
+ *
+ * @title:
+ * Base Interface
+ *
+ * @abstract:
+ * The FreeType~2 base font interface.
+ *
+ * @description:
+ * This section describes the most important public high-level API
+ * functions of FreeType~2.
+ *
+ * @order:
+ * FT_Library
+ * FT_Face
+ * FT_Size
+ * FT_GlyphSlot
+ * FT_CharMap
+ * FT_Encoding
+ * FT_ENC_TAG
+ *
+ * FT_FaceRec
+ *
+ * FT_FACE_FLAG_SCALABLE
+ * FT_FACE_FLAG_FIXED_SIZES
+ * FT_FACE_FLAG_FIXED_WIDTH
+ * FT_FACE_FLAG_HORIZONTAL
+ * FT_FACE_FLAG_VERTICAL
+ * FT_FACE_FLAG_COLOR
+ * FT_FACE_FLAG_SFNT
+ * FT_FACE_FLAG_CID_KEYED
+ * FT_FACE_FLAG_TRICKY
+ * FT_FACE_FLAG_KERNING
+ * FT_FACE_FLAG_MULTIPLE_MASTERS
+ * FT_FACE_FLAG_VARIATION
+ * FT_FACE_FLAG_GLYPH_NAMES
+ * FT_FACE_FLAG_EXTERNAL_STREAM
+ * FT_FACE_FLAG_HINTER
+ * FT_FACE_FLAG_SVG
+ * FT_FACE_FLAG_SBIX
+ * FT_FACE_FLAG_SBIX_OVERLAY
+ *
+ * FT_HAS_HORIZONTAL
+ * FT_HAS_VERTICAL
+ * FT_HAS_KERNING
+ * FT_HAS_FIXED_SIZES
+ * FT_HAS_GLYPH_NAMES
+ * FT_HAS_COLOR
+ * FT_HAS_MULTIPLE_MASTERS
+ * FT_HAS_SVG
+ * FT_HAS_SBIX
+ * FT_HAS_SBIX_OVERLAY
+ *
+ * FT_IS_SFNT
+ * FT_IS_SCALABLE
+ * FT_IS_FIXED_WIDTH
+ * FT_IS_CID_KEYED
+ * FT_IS_TRICKY
+ * FT_IS_NAMED_INSTANCE
+ * FT_IS_VARIATION
+ *
+ * FT_STYLE_FLAG_BOLD
+ * FT_STYLE_FLAG_ITALIC
+ *
+ * FT_SizeRec
+ * FT_Size_Metrics
+ *
+ * FT_GlyphSlotRec
+ * FT_Glyph_Metrics
+ * FT_SubGlyph
+ *
+ * FT_Bitmap_Size
+ *
+ * FT_Init_FreeType
+ * FT_Done_FreeType
+ *
+ * FT_New_Face
+ * FT_Done_Face
+ * FT_Reference_Face
+ * FT_New_Memory_Face
+ * FT_Face_Properties
+ * FT_Open_Face
+ * FT_Open_Args
+ * FT_Parameter
+ * FT_Attach_File
+ * FT_Attach_Stream
+ *
+ * FT_Set_Char_Size
+ * FT_Set_Pixel_Sizes
+ * FT_Request_Size
+ * FT_Select_Size
+ * FT_Size_Request_Type
+ * FT_Size_RequestRec
+ * FT_Size_Request
+ * FT_Set_Transform
+ * FT_Get_Transform
+ * FT_Load_Glyph
+ * FT_Get_Char_Index
+ * FT_Get_First_Char
+ * FT_Get_Next_Char
+ * FT_Get_Name_Index
+ * FT_Load_Char
+ *
+ * FT_OPEN_MEMORY
+ * FT_OPEN_STREAM
+ * FT_OPEN_PATHNAME
+ * FT_OPEN_DRIVER
+ * FT_OPEN_PARAMS
+ *
+ * FT_LOAD_DEFAULT
+ * FT_LOAD_RENDER
+ * FT_LOAD_MONOCHROME
+ * FT_LOAD_LINEAR_DESIGN
+ * FT_LOAD_NO_SCALE
+ * FT_LOAD_NO_HINTING
+ * FT_LOAD_NO_BITMAP
+ * FT_LOAD_SBITS_ONLY
+ * FT_LOAD_NO_AUTOHINT
+ * FT_LOAD_COLOR
+ *
+ * FT_LOAD_VERTICAL_LAYOUT
+ * FT_LOAD_IGNORE_TRANSFORM
+ * FT_LOAD_FORCE_AUTOHINT
+ * FT_LOAD_NO_RECURSE
+ * FT_LOAD_PEDANTIC
+ *
+ * FT_LOAD_TARGET_NORMAL
+ * FT_LOAD_TARGET_LIGHT
+ * FT_LOAD_TARGET_MONO
+ * FT_LOAD_TARGET_LCD
+ * FT_LOAD_TARGET_LCD_V
+ *
+ * FT_LOAD_TARGET_MODE
+ *
+ * FT_Render_Glyph
+ * FT_Render_Mode
+ * FT_Get_Kerning
+ * FT_Kerning_Mode
+ * FT_Get_Track_Kerning
+ * FT_Get_Glyph_Name
+ * FT_Get_Postscript_Name
+ *
+ * FT_CharMapRec
+ * FT_Select_Charmap
+ * FT_Set_Charmap
+ * FT_Get_Charmap_Index
+ *
+ * FT_Get_FSType_Flags
+ * FT_Get_SubGlyph_Info
+ *
+ * FT_Face_Internal
+ * FT_Size_Internal
+ * FT_Slot_Internal
+ *
+ * FT_FACE_FLAG_XXX
+ * FT_STYLE_FLAG_XXX
+ * FT_OPEN_XXX
+ * FT_LOAD_XXX
+ * FT_LOAD_TARGET_XXX
+ * FT_SUBGLYPH_FLAG_XXX
+ * FT_FSTYPE_XXX
+ *
+ * FT_HAS_FAST_GLYPHS
+ *
+ */
+
+
+ /**************************************************************************
+ *
+ * @struct:
+ * FT_Glyph_Metrics
+ *
+ * @description:
+ * A structure to model the metrics of a single glyph. The values are
+ * expressed in 26.6 fractional pixel format; if the flag
+ * @FT_LOAD_NO_SCALE has been used while loading the glyph, values are
+ * expressed in font units instead.
+ *
+ * @fields:
+ * width ::
+ * The glyph's width.
+ *
+ * height ::
+ * The glyph's height.
+ *
+ * horiBearingX ::
+ * Left side bearing for horizontal layout.
+ *
+ * horiBearingY ::
+ * Top side bearing for horizontal layout.
+ *
+ * horiAdvance ::
+ * Advance width for horizontal layout.
+ *
+ * vertBearingX ::
+ * Left side bearing for vertical layout.
+ *
+ * vertBearingY ::
+ * Top side bearing for vertical layout. Larger positive values mean
+ * further below the vertical glyph origin.
+ *
+ * vertAdvance ::
+ * Advance height for vertical layout. Positive values mean the glyph
+ * has a positive advance downward.
+ *
+ * @note:
+ * If not disabled with @FT_LOAD_NO_HINTING, the values represent
+ * dimensions of the hinted glyph (in case hinting is applicable).
+ *
+ * Stroking a glyph with an outside border does not increase
+ * `horiAdvance` or `vertAdvance`; you have to manually adjust these
+ * values to account for the added width and height.
+ *
+ * FreeType doesn't use the 'VORG' table data for CFF fonts because it
+ * doesn't have an interface to quickly retrieve the glyph height. The
+ * y~coordinate of the vertical origin can be simply computed as
+ * `vertBearingY + height` after loading a glyph.
+ */
+ typedef struct FT_Glyph_Metrics_
+ {
+ FT_Pos width;
+ FT_Pos height;
+
+ FT_Pos horiBearingX;
+ FT_Pos horiBearingY;
+ FT_Pos horiAdvance;
+
+ FT_Pos vertBearingX;
+ FT_Pos vertBearingY;
+ FT_Pos vertAdvance;
+
+ } FT_Glyph_Metrics;
+
+
+ /**************************************************************************
+ *
+ * @struct:
+ * FT_Bitmap_Size
+ *
+ * @description:
+ * This structure models the metrics of a bitmap strike (i.e., a set of
+ * glyphs for a given point size and resolution) in a bitmap font. It is
+ * used for the `available_sizes` field of @FT_Face.
+ *
+ * @fields:
+ * height ::
+ * The vertical distance, in pixels, between two consecutive baselines.
+ * It is always positive.
+ *
+ * width ::
+ * The average width, in pixels, of all glyphs in the strike.
+ *
+ * size ::
+ * The nominal size of the strike in 26.6 fractional points. This
+ * field is not very useful.
+ *
+ * x_ppem ::
+ * The horizontal ppem (nominal width) in 26.6 fractional pixels.
+ *
+ * y_ppem ::
+ * The vertical ppem (nominal height) in 26.6 fractional pixels.
+ *
+ * @note:
+ * Windows FNT:
+ * The nominal size given in a FNT font is not reliable. If the driver
+ * finds it incorrect, it sets `size` to some calculated values, and
+ * `x_ppem` and `y_ppem` to the pixel width and height given in the
+ * font, respectively.
+ *
+ * TrueType embedded bitmaps:
+ * `size`, `width`, and `height` values are not contained in the bitmap
+ * strike itself. They are computed from the global font parameters.
+ */
+ typedef struct FT_Bitmap_Size_
+ {
+ FT_Short height;
+ FT_Short width;
+
+ FT_Pos size;
+
+ FT_Pos x_ppem;
+ FT_Pos y_ppem;
+
+ } FT_Bitmap_Size;
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /* */
+ /* O B J E C T C L A S S E S */
+ /* */
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_Library
+ *
+ * @description:
+ * A handle to a FreeType library instance. Each 'library' is completely
+ * independent from the others; it is the 'root' of a set of objects like
+ * fonts, faces, sizes, etc.
+ *
+ * It also embeds a memory manager (see @FT_Memory), as well as a
+ * scan-line converter object (see @FT_Raster).
+ *
+ * [Since 2.5.6] In multi-threaded applications it is easiest to use one
+ * `FT_Library` object per thread. In case this is too cumbersome, a
+ * single `FT_Library` object across threads is possible also, as long as
+ * a mutex lock is used around @FT_New_Face and @FT_Done_Face.
+ *
+ * @note:
+ * Library objects are normally created by @FT_Init_FreeType, and
+ * destroyed with @FT_Done_FreeType. If you need reference-counting
+ * (cf. @FT_Reference_Library), use @FT_New_Library and @FT_Done_Library.
+ */
+ typedef struct FT_LibraryRec_ *FT_Library;
+
+
+ /**************************************************************************
+ *
+ * @section:
+ * module_management
+ *
+ */
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_Module
+ *
+ * @description:
+ * A handle to a given FreeType module object. A module can be a font
+ * driver, a renderer, or anything else that provides services to the
+ * former.
+ */
+ typedef struct FT_ModuleRec_* FT_Module;
+
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_Driver
+ *
+ * @description:
+ * A handle to a given FreeType font driver object. A font driver is a
+ * module capable of creating faces from font files.
+ */
+ typedef struct FT_DriverRec_* FT_Driver;
+
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_Renderer
+ *
+ * @description:
+ * A handle to a given FreeType renderer. A renderer is a module in
+ * charge of converting a glyph's outline image to a bitmap. It supports
+ * a single glyph image format, and one or more target surface depths.
+ */
+ typedef struct FT_RendererRec_* FT_Renderer;
+
+
+ /**************************************************************************
+ *
+ * @section:
+ * base_interface
+ *
+ */
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_Face
+ *
+ * @description:
+ * A handle to a typographic face object. A face object models a given
+ * typeface, in a given style.
+ *
+ * @note:
+ * A face object also owns a single @FT_GlyphSlot object, as well as one
+ * or more @FT_Size objects.
+ *
+ * Use @FT_New_Face or @FT_Open_Face to create a new face object from a
+ * given filepath or a custom input stream.
+ *
+ * Use @FT_Done_Face to destroy it (along with its slot and sizes).
+ *
+ * An `FT_Face` object can only be safely used from one thread at a time.
+ * Similarly, creation and destruction of `FT_Face` with the same
+ * @FT_Library object can only be done from one thread at a time. On the
+ * other hand, functions like @FT_Load_Glyph and its siblings are
+ * thread-safe and do not need the lock to be held as long as the same
+ * `FT_Face` object is not used from multiple threads at the same time.
+ *
+ * @also:
+ * See @FT_FaceRec for the publicly accessible fields of a given face
+ * object.
+ */
+ typedef struct FT_FaceRec_* FT_Face;
+
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_Size
+ *
+ * @description:
+ * A handle to an object that models a face scaled to a given character
+ * size.
+ *
+ * @note:
+ * An @FT_Face has one _active_ `FT_Size` object that is used by
+ * functions like @FT_Load_Glyph to determine the scaling transformation
+ * that in turn is used to load and hint glyphs and metrics.
+ *
+ * A newly created `FT_Size` object contains only meaningless zero values.
+ * You must use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes, @FT_Request_Size
+ * or even @FT_Select_Size to change the content (i.e., the scaling
+ * values) of the active `FT_Size`. Otherwise, the scaling and hinting
+ * will not be performed.
+ *
+ * You can use @FT_New_Size to create additional size objects for a given
+ * @FT_Face, but they won't be used by other functions until you activate
+ * it through @FT_Activate_Size. Only one size can be activated at any
+ * given time per face.
+ *
+ * @also:
+ * See @FT_SizeRec for the publicly accessible fields of a given size
+ * object.
+ */
+ typedef struct FT_SizeRec_* FT_Size;
+
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_GlyphSlot
+ *
+ * @description:
+ * A handle to a given 'glyph slot'. A slot is a container that can hold
+ * any of the glyphs contained in its parent face.
+ *
+ * In other words, each time you call @FT_Load_Glyph or @FT_Load_Char,
+ * the slot's content is erased by the new glyph data, i.e., the glyph's
+ * metrics, its image (bitmap or outline), and other control information.
+ *
+ * @also:
+ * See @FT_GlyphSlotRec for the publicly accessible glyph fields.
+ */
+ typedef struct FT_GlyphSlotRec_* FT_GlyphSlot;
+
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_CharMap
+ *
+ * @description:
+ * A handle to a character map (usually abbreviated to 'charmap'). A
+ * charmap is used to translate character codes in a given encoding into
+ * glyph indexes for its parent's face. Some font formats may provide
+ * several charmaps per font.
+ *
+ * Each face object owns zero or more charmaps, but only one of them can
+ * be 'active', providing the data used by @FT_Get_Char_Index or
+ * @FT_Load_Char.
+ *
+ * The list of available charmaps in a face is available through the
+ * `face->num_charmaps` and `face->charmaps` fields of @FT_FaceRec.
+ *
+ * The currently active charmap is available as `face->charmap`. You
+ * should call @FT_Set_Charmap to change it.
+ *
+ * @note:
+ * When a new face is created (either through @FT_New_Face or
+ * @FT_Open_Face), the library looks for a Unicode charmap within the
+ * list and automatically activates it. If there is no Unicode charmap,
+ * FreeType doesn't set an 'active' charmap.
+ *
+ * @also:
+ * See @FT_CharMapRec for the publicly accessible fields of a given
+ * character map.
+ */
+ typedef struct FT_CharMapRec_* FT_CharMap;
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_ENC_TAG
+ *
+ * @description:
+ * This macro converts four-letter tags into an unsigned long. It is
+ * used to define 'encoding' identifiers (see @FT_Encoding).
+ *
+ * @note:
+ * Since many 16-bit compilers don't like 32-bit enumerations, you should
+ * redefine this macro in case of problems to something like this:
+ *
+ * ```
+ * #define FT_ENC_TAG( value, a, b, c, d ) value
+ * ```
+ *
+ * to get a simple enumeration without assigning special numbers.
+ */
+
+#ifndef FT_ENC_TAG
+
+#define FT_ENC_TAG( value, a, b, c, d ) \
+ value = ( ( FT_STATIC_BYTE_CAST( FT_UInt32, a ) << 24 ) | \
+ ( FT_STATIC_BYTE_CAST( FT_UInt32, b ) << 16 ) | \
+ ( FT_STATIC_BYTE_CAST( FT_UInt32, c ) << 8 ) | \
+ FT_STATIC_BYTE_CAST( FT_UInt32, d ) )
+
+#endif /* FT_ENC_TAG */
+
+
+ /**************************************************************************
+ *
+ * @enum:
+ * FT_Encoding
+ *
+ * @description:
+ * An enumeration to specify character sets supported by charmaps. Used
+ * in the @FT_Select_Charmap API function.
+ *
+ * @note:
+ * Despite the name, this enumeration lists specific character
+ * repertories (i.e., charsets), and not text encoding methods (e.g.,
+ * UTF-8, UTF-16, etc.).
+ *
+ * Other encodings might be defined in the future.
+ *
+ * @values:
+ * FT_ENCODING_NONE ::
+ * The encoding value~0 is reserved for all formats except BDF, PCF,
+ * and Windows FNT; see below for more information.
+ *
+ * FT_ENCODING_UNICODE ::
+ * The Unicode character set. This value covers all versions of the
+ * Unicode repertoire, including ASCII and Latin-1. Most fonts include
+ * a Unicode charmap, but not all of them.
+ *
+ * For example, if you want to access Unicode value U+1F028 (and the
+ * font contains it), use value 0x1F028 as the input value for
+ * @FT_Get_Char_Index.
+ *
+ * FT_ENCODING_MS_SYMBOL ::
+ * Microsoft Symbol encoding, used to encode mathematical symbols and
+ * wingdings. For more information, see
+ * 'https://www.microsoft.com/typography/otspec/recom.htm#non-standard-symbol-fonts',
+ * 'http://www.kostis.net/charsets/symbol.htm', and
+ * 'http://www.kostis.net/charsets/wingding.htm'.
+ *
+ * This encoding uses character codes from the PUA (Private Unicode
+ * Area) in the range U+F020-U+F0FF.
+ *
+ * FT_ENCODING_SJIS ::
+ * Shift JIS encoding for Japanese. More info at
+ * 'https://en.wikipedia.org/wiki/Shift_JIS'. See note on multi-byte
+ * encodings below.
+ *
+ * FT_ENCODING_PRC ::
+ * Corresponds to encoding systems mainly for Simplified Chinese as
+ * used in People's Republic of China (PRC). The encoding layout is
+ * based on GB~2312 and its supersets GBK and GB~18030.
+ *
+ * FT_ENCODING_BIG5 ::
+ * Corresponds to an encoding system for Traditional Chinese as used in
+ * Taiwan and Hong Kong.
+ *
+ * FT_ENCODING_WANSUNG ::
+ * Corresponds to the Korean encoding system known as Extended Wansung
+ * (MS Windows code page 949). For more information see
+ * 'https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit949.txt'.
+ *
+ * FT_ENCODING_JOHAB ::
+ * The Korean standard character set (KS~C 5601-1992), which
+ * corresponds to MS Windows code page 1361. This character set
+ * includes all possible Hangul character combinations.
+ *
+ * FT_ENCODING_ADOBE_LATIN_1 ::
+ * Corresponds to a Latin-1 encoding as defined in a Type~1 PostScript
+ * font. It is limited to 256 character codes.
+ *
+ * FT_ENCODING_ADOBE_STANDARD ::
+ * Adobe Standard encoding, as found in Type~1, CFF, and OpenType/CFF
+ * fonts. It is limited to 256 character codes.
+ *
+ * FT_ENCODING_ADOBE_EXPERT ::
+ * Adobe Expert encoding, as found in Type~1, CFF, and OpenType/CFF
+ * fonts. It is limited to 256 character codes.
+ *
+ * FT_ENCODING_ADOBE_CUSTOM ::
+ * Corresponds to a custom encoding, as found in Type~1, CFF, and
+ * OpenType/CFF fonts. It is limited to 256 character codes.
+ *
+ * FT_ENCODING_APPLE_ROMAN ::
+ * Apple roman encoding. Many TrueType and OpenType fonts contain a
+ * charmap for this 8-bit encoding, since older versions of Mac OS are
+ * able to use it.
+ *
+ * FT_ENCODING_OLD_LATIN_2 ::
+ * This value is deprecated and was neither used nor reported by
+ * FreeType. Don't use or test for it.
+ *
+ * FT_ENCODING_MS_SJIS ::
+ * Same as FT_ENCODING_SJIS. Deprecated.
+ *
+ * FT_ENCODING_MS_GB2312 ::
+ * Same as FT_ENCODING_PRC. Deprecated.
+ *
+ * FT_ENCODING_MS_BIG5 ::
+ * Same as FT_ENCODING_BIG5. Deprecated.
+ *
+ * FT_ENCODING_MS_WANSUNG ::
+ * Same as FT_ENCODING_WANSUNG. Deprecated.
+ *
+ * FT_ENCODING_MS_JOHAB ::
+ * Same as FT_ENCODING_JOHAB. Deprecated.
+ *
+ * @note:
+ * When loading a font, FreeType makes a Unicode charmap active if
+ * possible (either if the font provides such a charmap, or if FreeType
+ * can synthesize one from PostScript glyph name dictionaries; in either
+ * case, the charmap is tagged with `FT_ENCODING_UNICODE`). If such a
+ * charmap is synthesized, it is placed at the first position of the
+ * charmap array.
+ *
+ * All other encodings are considered legacy and tagged only if
+ * explicitly defined in the font file. Otherwise, `FT_ENCODING_NONE` is
+ * used.
+ *
+ * `FT_ENCODING_NONE` is set by the BDF and PCF drivers if the charmap is
+ * neither Unicode nor ISO-8859-1 (otherwise it is set to
+ * `FT_ENCODING_UNICODE`). Use @FT_Get_BDF_Charset_ID to find out which
+ * encoding is really present. If, for example, the `cs_registry` field
+ * is 'KOI8' and the `cs_encoding` field is 'R', the font is encoded in
+ * KOI8-R.
+ *
+ * `FT_ENCODING_NONE` is always set (with a single exception) by the
+ * winfonts driver. Use @FT_Get_WinFNT_Header and examine the `charset`
+ * field of the @FT_WinFNT_HeaderRec structure to find out which encoding
+ * is really present. For example, @FT_WinFNT_ID_CP1251 (204) means
+ * Windows code page 1251 (for Russian).
+ *
+ * `FT_ENCODING_NONE` is set if `platform_id` is @TT_PLATFORM_MACINTOSH
+ * and `encoding_id` is not `TT_MAC_ID_ROMAN` (otherwise it is set to
+ * `FT_ENCODING_APPLE_ROMAN`).
+ *
+ * If `platform_id` is @TT_PLATFORM_MACINTOSH, use the function
+ * @FT_Get_CMap_Language_ID to query the Mac language ID that may be
+ * needed to be able to distinguish Apple encoding variants. See
+ *
+ * https://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt
+ *
+ * to get an idea how to do that. Basically, if the language ID is~0,
+ * don't use it, otherwise subtract 1 from the language ID. Then examine
+ * `encoding_id`. If, for example, `encoding_id` is `TT_MAC_ID_ROMAN`
+ * and the language ID (minus~1) is `TT_MAC_LANGID_GREEK`, it is the
+ * Greek encoding, not Roman. `TT_MAC_ID_ARABIC` with
+ * `TT_MAC_LANGID_FARSI` means the Farsi variant the Arabic encoding.
+ */
+ typedef enum FT_Encoding_
+ {
+ FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ),
+
+ FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ),
+ FT_ENC_TAG( FT_ENCODING_UNICODE, 'u', 'n', 'i', 'c' ),
+
+ FT_ENC_TAG( FT_ENCODING_SJIS, 's', 'j', 'i', 's' ),
+ FT_ENC_TAG( FT_ENCODING_PRC, 'g', 'b', ' ', ' ' ),
+ FT_ENC_TAG( FT_ENCODING_BIG5, 'b', 'i', 'g', '5' ),
+ FT_ENC_TAG( FT_ENCODING_WANSUNG, 'w', 'a', 'n', 's' ),
+ FT_ENC_TAG( FT_ENCODING_JOHAB, 'j', 'o', 'h', 'a' ),
+
+ /* for backward compatibility */
+ FT_ENCODING_GB2312 = FT_ENCODING_PRC,
+ FT_ENCODING_MS_SJIS = FT_ENCODING_SJIS,
+ FT_ENCODING_MS_GB2312 = FT_ENCODING_PRC,
+ FT_ENCODING_MS_BIG5 = FT_ENCODING_BIG5,
+ FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG,
+ FT_ENCODING_MS_JOHAB = FT_ENCODING_JOHAB,
+
+ FT_ENC_TAG( FT_ENCODING_ADOBE_STANDARD, 'A', 'D', 'O', 'B' ),
+ FT_ENC_TAG( FT_ENCODING_ADOBE_EXPERT, 'A', 'D', 'B', 'E' ),
+ FT_ENC_TAG( FT_ENCODING_ADOBE_CUSTOM, 'A', 'D', 'B', 'C' ),
+ FT_ENC_TAG( FT_ENCODING_ADOBE_LATIN_1, 'l', 'a', 't', '1' ),
+
+ FT_ENC_TAG( FT_ENCODING_OLD_LATIN_2, 'l', 'a', 't', '2' ),
+
+ FT_ENC_TAG( FT_ENCODING_APPLE_ROMAN, 'a', 'r', 'm', 'n' )
+
+ } FT_Encoding;
+
+
+ /* these constants are deprecated; use the corresponding `FT_Encoding` */
+ /* values instead */
+#define ft_encoding_none FT_ENCODING_NONE
+#define ft_encoding_unicode FT_ENCODING_UNICODE
+#define ft_encoding_symbol FT_ENCODING_MS_SYMBOL
+#define ft_encoding_latin_1 FT_ENCODING_ADOBE_LATIN_1
+#define ft_encoding_latin_2 FT_ENCODING_OLD_LATIN_2
+#define ft_encoding_sjis FT_ENCODING_SJIS
+#define ft_encoding_gb2312 FT_ENCODING_PRC
+#define ft_encoding_big5 FT_ENCODING_BIG5
+#define ft_encoding_wansung FT_ENCODING_WANSUNG
+#define ft_encoding_johab FT_ENCODING_JOHAB
+
+#define ft_encoding_adobe_standard FT_ENCODING_ADOBE_STANDARD
+#define ft_encoding_adobe_expert FT_ENCODING_ADOBE_EXPERT
+#define ft_encoding_adobe_custom FT_ENCODING_ADOBE_CUSTOM
+#define ft_encoding_apple_roman FT_ENCODING_APPLE_ROMAN
+
+
+ /**************************************************************************
+ *
+ * @struct:
+ * FT_CharMapRec
+ *
+ * @description:
+ * The base charmap structure.
+ *
+ * @fields:
+ * face ::
+ * A handle to the parent face object.
+ *
+ * encoding ::
+ * An @FT_Encoding tag identifying the charmap. Use this with
+ * @FT_Select_Charmap.
+ *
+ * platform_id ::
+ * An ID number describing the platform for the following encoding ID.
+ * This comes directly from the TrueType specification and gets
+ * emulated for other formats.
+ *
+ * encoding_id ::
+ * A platform-specific encoding number. This also comes from the
+ * TrueType specification and gets emulated similarly.
+ */
+ typedef struct FT_CharMapRec_
+ {
+ FT_Face face;
+ FT_Encoding encoding;
+ FT_UShort platform_id;
+ FT_UShort encoding_id;
+
+ } FT_CharMapRec;
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /* */
+ /* B A S E O B J E C T C L A S S E S */
+ /* */
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+ /**************************************************************************
+ *
+ * @type:
+ * FT_Face_Internal
+ *
+ * @description:
+ * An opaque handle to an `FT_Face_InternalRec` structure that models the
+ * private data of a given @FT_Face object.
+ *
+ * This structure might change between releases of FreeType~2 and is not
+ * generally available to client applications.
+ */
+ typedef struct FT_Face_InternalRec_* FT_Face_Internal;
+
+
+ /**************************************************************************
+ *
+ * @struct:
+ * FT_FaceRec
+ *
+ * @description:
+ * FreeType root face class structure. A face object models a typeface
+ * in a font file.
+ *
+ * @fields:
+ * num_faces ::
+ * The number of faces in the font file. Some font formats can have
+ * multiple faces in a single font file.
+ *
+ * face_index ::
+ * This field holds two different values. Bits 0-15 are the index of
+ * the face in the font file (starting with value~0). They are set
+ * to~0 if there is only one face in the font file.
+ *
+ * [Since 2.6.1] Bits 16-30 are relevant to GX and OpenType variation
+ * fonts only, holding the named instance index for the current face
+ * index (starting with value~1; value~0 indicates font access without
+ * a named instance). For non-variation fonts, bits 16-30 are ignored.
+ * If we have the third named instance of face~4, say, `face_index` is
+ * set to 0x00030004.
+ *
+ * Bit 31 is always zero (this is, `face_index` is always a positive
+ * value).
+ *
+ * [Since 2.9] Changing the design coordinates with
+ * @FT_Set_Var_Design_Coordinates or @FT_Set_Var_Blend_Coordinates does
+ * not influence the named instance index value (only
+ * @FT_Set_Named_Instance does that).
+ *
+ * face_flags ::
+ * A set of bit flags that give important information about the face;
+ * see @FT_FACE_FLAG_XXX for the details.
+ *
+ * style_flags ::
+ * The lower 16~bits contain a set of bit flags indicating the style of
+ * the face; see @FT_STYLE_FLAG_XXX for the details.
+ *
+ * [Since 2.6.1] Bits 16-30 hold the number of named instances
+ * available for the current face if we have a GX or OpenType variation
+ * (sub)font. Bit 31 is always zero (this is, `style_flags` is always
+ * a positive value). Note that a variation font has always at least
+ * one named instance, namely the default instance.
+ *
+ * num_glyphs ::
+ * The number of glyphs in the face. If the face is scalable and has
+ * sbits (see `num_fixed_sizes`), it is set to the number of outline
+ * glyphs.
+ *
+ * For CID-keyed fonts (not in an SFNT wrapper) this value gives the
+ * highest CID used in the font.
+ *
+ * family_name ::
+ * The face's family name. This is an ASCII string, usually in
+ * English, that describes the typeface's family (like 'Times New
+ * Roman', 'Bodoni', 'Garamond', etc). This is a least common
+ * denominator used to list fonts. Some formats (TrueType & OpenType)
+ * provide localized and Unicode versions of this string. Applications
+ * should use the format-specific interface to access them. Can be
+ * `NULL` (e.g., in fonts embedded in a PDF file).
+ *
+ * In case the font doesn't provide a specific family name entry,
+ * FreeType tries to synthesize one, deriving it from other name
+ * entries.
+ *
+ * style_name ::
+ * The face's style name. This is an ASCII string, usually in English,
+ * that describes the typeface's style (like 'Italic', 'Bold',
+ * 'Condensed', etc). Not all font formats provide a style name, so
+ * this field is optional, and can be set to `NULL`. As for
+ * `family_name`, some formats provide localized and Unicode versions
+ * of this string. Applications should use the format-specific
+ * interface to access them.
+ *
+ * num_fixed_sizes ::
+ * The number of bitmap strikes in the face. Even if the face is
+ * scalable, there might still be bitmap strikes, which are called
+ * 'sbits' in that case.
+ *
+ * available_sizes ::
+ * An array of @FT_Bitmap_Size for all bitmap strikes in the face. It
+ * is set to `NULL` if there is no bitmap strike.
+ *
+ * Note that FreeType tries to sanitize the strike data since they are
+ * sometimes sloppy or incorrect, but this can easily fail.
+ *
+ * num_charmaps ::
+ * The number of charmaps in the face.
+ *
+ * charmaps ::
+ * An array of the charmaps of the face.
+ *
+ * generic ::
+ * A field reserved for client uses. See the @FT_Generic type
+ * description.
+ *
+ * bbox ::
+ * The font bounding box. Coordinates are expressed in font units (see
+ * `units_per_EM`). The box is large enough to contain any glyph from
+ * the font. Thus, `bbox.yMax` can be seen as the 'maximum ascender',
+ * and `bbox.yMin` as the 'minimum descender'. Only relevant for
+ * scalable formats.
+ *
+ * Note that the bounding box might be off by (at least) one pixel for
+ * hinted fonts. See @FT_Size_Metrics for further discussion.
+ *
+ * Note that the bounding box does not vary in OpenType variable fonts
+ * and should only be used in relation to the default instance.
+ *
+ * units_per_EM ::
+ * The number of font units per EM square for this face. This is
+ * typically 2048 for TrueType fonts, and 1000 for Type~1 fonts. Only
+ * relevant for scalable formats.
+ *
+ * ascender ::
+ * The typographic ascender of the face, expressed in font units. For
+ * font formats not having this information, it is set to `bbox.yMax`.
+ * Only relevant for scalable formats.
+ *
+ * descender ::
+ * The typographic descender of the face, expressed in font units. For
+ * font formats not having this information, it is set to `bbox.yMin`.
+ * Note that this field is negative for values below the baseline.
+ * Only relevant for scalable formats.
+ *
+ * height ::
+ * This value is the vertical distance between two consecutive
+ * baselines, expressed in font units. It is always positive. Only
+ * relevant for scalable formats.
+ *
+ * If you want the global glyph height, use `ascender - descender`.
+ *
+ * max_advance_width ::
+ * The maximum advance width, in font units, for all glyphs in this
+ * face. This can be used to make word wrapping computations faster.
+ * Only relevant for scalable formats.
+ *
+ * max_advance_height ::
+ * The maximum advance height, in font units, for all glyphs in this
+ * face. This is only relevant for vertical layouts, and is set to
+ * `height` for fonts that do not provide vertical metrics. Only
+ * relevant for scalable formats.
+ *
+ * underline_position ::
+ * The position, in font units, of the underline line for this face.
+ * It is the center of the underlining stem. Only relevant for
+ * scalable formats.
+ *
+ * underline_thickness ::
+ * The thickness, in font units, of the underline for this face. Only
+ * relevant for scalable formats.
+ *
+ * glyph ::
+ * The face's associated glyph slot(s).
+ *
+ * size ::
+ * The current active size for this face.
+ *
+ * charmap ::
+ * The current active charmap for this face.
+ *
+ * @note:
+ * Fields may be changed after a call to @FT_Attach_File or
+ * @FT_Attach_Stream.
+ *
+ * For an OpenType variation font, the values of the following fields can
+ * change after a call to @FT_Set_Var_Design_Coordinates (and friends) if
+ * the font contains an 'MVAR' table: `ascender`, `descender`, `height`,
+ * `underline_position`, and `underline_thickness`.
+ *
+ * Especially for TrueType fonts see also the documentation for
+ * @FT_Size_Metrics.
+ */
+ typedef struct FT_FaceRec_
+ {
+ FT_Long num_faces;
+ FT_Long face_index;
+
+ FT_Long face_flags;
+ FT_Long style_flags;
+
+ FT_Long num_glyphs;
+
+ FT_String* family_name;
+ FT_String* style_name;
+
+ FT_Int num_fixed_sizes;
+ FT_Bitmap_Size* available_sizes;
+
+ FT_Int num_charmaps;
+ FT_CharMap* charmaps;
+
+ FT_Generic generic;
+
+ /*# The following member variables (down to `underline_thickness`) */
+ /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size */
+ /*# for bitmap fonts. */
+ FT_BBox bbox;
+
+ FT_UShort units_per_EM;
+ FT_Short ascender;
+ FT_Short descender;
+ FT_Short height;
+
+ FT_Short max_advance_width;
+ FT_Short max_advance_height;
+
+ FT_Short underline_position;
+ FT_Short underline_thickness;
+
+ FT_GlyphSlot glyph;
+ FT_Size size;
+ FT_CharMap charmap;
+
+ /*@private begin */
+
+ FT_Driver driver;
+ FT_Memory memory;
+ FT_Stream stream;
+
+ FT_ListRec sizes_list;
+
+ FT_Generic autohint; /* face-specific auto-hinter data */
+ void* extensions; /* unused */
+
+ FT_Face_Internal internal;
+
+ /*@private end */
+
+ } FT_FaceRec;
+
+
+ /**************************************************************************
+ *
+ * @enum:
+ * FT_FACE_FLAG_XXX
+ *
+ * @description:
+ * A list of bit flags used in the `face_flags` field of the @FT_FaceRec
+ * structure. They inform client applications of properties of the
+ * corresponding face.
+ *
+ * @values:
+ * FT_FACE_FLAG_SCALABLE ::
+ * The face contains outline glyphs. Note that a face can contain
+ * bitmap strikes also, i.e., a face can have both this flag and
+ * @FT_FACE_FLAG_FIXED_SIZES set.
+ *
+ * FT_FACE_FLAG_FIXED_SIZES ::
+ * The face contains bitmap strikes. See also the `num_fixed_sizes`
+ * and `available_sizes` fields of @FT_FaceRec.
+ *
+ * FT_FACE_FLAG_FIXED_WIDTH ::
+ * The face contains fixed-width characters (like Courier, Lucida,
+ * MonoType, etc.).
+ *
+ * FT_FACE_FLAG_SFNT ::
+ * The face uses the SFNT storage scheme. For now, this means TrueType
+ * and OpenType.
+ *
+ * FT_FACE_FLAG_HORIZONTAL ::
+ * The face contains horizontal glyph metrics. This should be set for
+ * all common formats.
+ *
+ * FT_FACE_FLAG_VERTICAL ::
+ * The face contains vertical glyph metrics. This is only available in
+ * some formats, not all of them.
+ *
+ * FT_FACE_FLAG_KERNING ::
+ * The face contains kerning information. If set, the kerning distance
+ * can be retrieved using the function @FT_Get_Kerning. Otherwise the
+ * function always return the vector (0,0). Note that FreeType doesn't
+ * handle kerning data from the SFNT 'GPOS' table (as present in many
+ * OpenType fonts).
+ *
+ * FT_FACE_FLAG_FAST_GLYPHS ::
+ * THIS FLAG IS DEPRECATED. DO NOT USE OR TEST IT.
+ *
+ * FT_FACE_FLAG_MULTIPLE_MASTERS ::
+ * The face contains multiple masters and is capable of interpolating
+ * between them. Supported formats are Adobe MM, TrueType GX, and
+ * OpenType variation fonts.
+ *
+ * See section @multiple_masters for API details.
+ *
+ * FT_FACE_FLAG_GLYPH_NAMES ::
+ * The face contains glyph names, which can be retrieved using
+ * @FT_Get_Glyph_Name. Note that some TrueType fonts contain broken
+ * glyph name tables. Use the function @FT_Has_PS_Glyph_Names when
+ * needed.
+ *
+ * FT_FACE_FLAG_EXTERNAL_STREAM ::
+ * Used internally by FreeType to indicate that a face's stream was
+ * provided by the client application and should not be destroyed when
+ * @FT_Done_Face is called. Don't read or test this flag.
+ *
+ * FT_FACE_FLAG_HINTER ::
+ * The font driver has a hinting machine of its own. For example, with
+ * TrueType fonts, it makes sense to use data from the SFNT 'gasp'
+ * table only if the native TrueType hinting engine (with the bytecode
+ * interpreter) is available and active.
+ *
+ * FT_FACE_FLAG_CID_KEYED ::
+ * The face is CID-keyed. In that case, the face is not accessed by
+ * glyph indices but by CID values. For subsetted CID-keyed fonts this
+ * has the consequence that not all index values are a valid argument
+ * to @FT_Load_Glyph. Only the CID values for which corresponding
+ * glyphs in the subsetted font exist make `FT_Load_Glyph` return
+ * successfully; in all other cases you get an
+ * `FT_Err_Invalid_Argument` error.
+ *
+ * Note that CID-keyed fonts that are in an SFNT wrapper (this is, all
+ * OpenType/CFF fonts) don't have this flag set since the glyphs are
+ * accessed in the normal way (using contiguous indices); the
+ * 'CID-ness' isn't visible to the application.
+ *
+ * FT_FACE_FLAG_TRICKY ::
+ * The face is 'tricky', this is, it always needs the font format's
+ * native hinting engine to get a reasonable result. A typical example
+ * is the old Chinese font `mingli.ttf` (but not `mingliu.ttc`) that
+ * uses TrueType bytecode instructions to move and scale all of its
+ * subglyphs.
+ *
+ * It is not possible to auto-hint such fonts using
+ * @FT_LOAD_FORCE_AUTOHINT; it will also ignore @FT_LOAD_NO_HINTING.
+ * You have to set both @FT_LOAD_NO_HINTING and @FT_LOAD_NO_AUTOHINT to
+ * really disable hinting; however, you probably never want this except
+ * for demonstration purposes.
+ *
+ * Currently, there are about a dozen TrueType fonts in the list of
+ * tricky fonts; they are hard-coded in file `ttobjs.c`.
+ *
+ * FT_FACE_FLAG_COLOR ::
+ * [Since 2.5.1] The face has color glyph tables. See @FT_LOAD_COLOR
+ * for more information.
+ *
+ * FT_FACE_FLAG_VARIATION ::
+ * [Since 2.9] Set if the current face (or named instance) has been
+ * altered with @FT_Set_MM_Design_Coordinates,
+ * @FT_Set_Var_Design_Coordinates, or @FT_Set_Var_Blend_Coordinates.
+ * This flag is unset by a call to @FT_Set_Named_Instance.
+ *
+ * FT_FACE_FLAG_SVG ::
+ * [Since 2.12] The face has an 'SVG~' OpenType table.
+ *
+ * FT_FACE_FLAG_SBIX ::
+ * [Since 2.12] The face has an 'sbix' OpenType table *and* outlines.
+ * For such fonts, @FT_FACE_FLAG_SCALABLE is not set by default to
+ * retain backward compatibility.
+ *
+ * FT_FACE_FLAG_SBIX_OVERLAY ::
+ * [Since 2.12] The face has an 'sbix' OpenType table where outlines
+ * should be drawn on top of bitmap strikes.
+ *
+ */
+#define FT_FACE_FLAG_SCALABLE ( 1L << 0 )
+#define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 )
+#define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 )
+#define FT_FACE_FLAG_SFNT ( 1L << 3 )
+#define FT_FACE_FLAG_HORIZONTAL ( 1L << 4 )
+#define FT_FACE_FLAG_VERTICAL ( 1L << 5 )
+#define FT_FACE_FLAG_KERNING ( 1L << 6 )
+#define FT_FACE_FLAG_FAST_GLYPHS ( 1L << 7 )
+#define FT_FACE_FLAG_MULTIPLE_MASTERS ( 1L << 8 )
+#define FT_FACE_FLAG_GLYPH_NAMES ( 1L << 9 )
+#define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 )
+#define FT_FACE_FLAG_HINTER ( 1L << 11 )
+#define FT_FACE_FLAG_CID_KEYED ( 1L << 12 )
+#define FT_FACE_FLAG_TRICKY ( 1L << 13 )
+#define FT_FACE_FLAG_COLOR ( 1L << 14 )
+#define FT_FACE_FLAG_VARIATION ( 1L << 15 )
+#define FT_FACE_FLAG_SVG ( 1L << 16 )
+#define FT_FACE_FLAG_SBIX ( 1L << 17 )
+#define FT_FACE_FLAG_SBIX_OVERLAY ( 1L << 18 )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_HAS_HORIZONTAL
+ *
+ * @description:
+ * A macro that returns true whenever a face object contains horizontal
+ * metrics (this is true for all font formats though).
+ *
+ * @also:
+ * @FT_HAS_VERTICAL can be used to check for vertical metrics.
+ *
+ */
+#define FT_HAS_HORIZONTAL( face ) \
+ ( !!( (face)->face_flags & FT_FACE_FLAG_HORIZONTAL ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_HAS_VERTICAL
+ *
+ * @description:
+ * A macro that returns true whenever a face object contains real
+ * vertical metrics (and not only synthesized ones).
+ *
+ */
+#define FT_HAS_VERTICAL( face ) \
+ ( !!( (face)->face_flags & FT_FACE_FLAG_VERTICAL ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_HAS_KERNING
+ *
+ * @description:
+ * A macro that returns true whenever a face object contains kerning data
+ * that can be accessed with @FT_Get_Kerning.
+ *
+ */
+#define FT_HAS_KERNING( face ) \
+ ( !!( (face)->face_flags & FT_FACE_FLAG_KERNING ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_IS_SCALABLE
+ *
+ * @description:
+ * A macro that returns true whenever a face object contains a scalable
+ * font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, and
+ * PFR font formats).
+ *
+ */
+#define FT_IS_SCALABLE( face ) \
+ ( !!( (face)->face_flags & FT_FACE_FLAG_SCALABLE ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_IS_SFNT
+ *
+ * @description:
+ * A macro that returns true whenever a face object contains a font whose
+ * format is based on the SFNT storage scheme. This usually means:
+ * TrueType fonts, OpenType fonts, as well as SFNT-based embedded bitmap
+ * fonts.
+ *
+ * If this macro is true, all functions defined in @FT_SFNT_NAMES_H and
+ * @FT_TRUETYPE_TABLES_H are available.
+ *
+ */
+#define FT_IS_SFNT( face ) \
+ ( !!( (face)->face_flags & FT_FACE_FLAG_SFNT ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_IS_FIXED_WIDTH
+ *
+ * @description:
+ * A macro that returns true whenever a face object contains a font face
+ * that contains fixed-width (or 'monospace', 'fixed-pitch', etc.)
+ * glyphs.
+ *
+ */
+#define FT_IS_FIXED_WIDTH( face ) \
+ ( !!( (face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_HAS_FIXED_SIZES
+ *
+ * @description:
+ * A macro that returns true whenever a face object contains some
+ * embedded bitmaps. See the `available_sizes` field of the @FT_FaceRec
+ * structure.
+ *
+ */
+#define FT_HAS_FIXED_SIZES( face ) \
+ ( !!( (face)->face_flags & FT_FACE_FLAG_FIXED_SIZES ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_HAS_FAST_GLYPHS
+ *
+ * @description:
+ * Deprecated.
+ *
+ */
+#define FT_HAS_FAST_GLYPHS( face ) 0
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_HAS_GLYPH_NAMES
+ *
+ * @description:
+ * A macro that returns true whenever a face object contains some glyph
+ * names that can be accessed through @FT_Get_Glyph_Name.
+ *
+ */
+#define FT_HAS_GLYPH_NAMES( face ) \
+ ( !!( (face)->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_HAS_MULTIPLE_MASTERS
+ *
+ * @description:
+ * A macro that returns true whenever a face object contains some
+ * multiple masters. The functions provided by @FT_MULTIPLE_MASTERS_H
+ * are then available to choose the exact design you want.
+ *
+ */
+#define FT_HAS_MULTIPLE_MASTERS( face ) \
+ ( !!( (face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_IS_NAMED_INSTANCE
+ *
+ * @description:
+ * A macro that returns true whenever a face object is a named instance
+ * of a GX or OpenType variation font.
+ *
+ * [Since 2.9] Changing the design coordinates with
+ * @FT_Set_Var_Design_Coordinates or @FT_Set_Var_Blend_Coordinates does
+ * not influence the return value of this macro (only
+ * @FT_Set_Named_Instance does that).
+ *
+ * @since:
+ * 2.7
+ *
+ */
+#define FT_IS_NAMED_INSTANCE( face ) \
+ ( !!( (face)->face_index & 0x7FFF0000L ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_IS_VARIATION
+ *
+ * @description:
+ * A macro that returns true whenever a face object has been altered by
+ * @FT_Set_MM_Design_Coordinates, @FT_Set_Var_Design_Coordinates, or
+ * @FT_Set_Var_Blend_Coordinates.
+ *
+ * @since:
+ * 2.9
+ *
+ */
+#define FT_IS_VARIATION( face ) \
+ ( !!( (face)->face_flags & FT_FACE_FLAG_VARIATION ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_IS_CID_KEYED
+ *
+ * @description:
+ * A macro that returns true whenever a face object contains a CID-keyed
+ * font. See the discussion of @FT_FACE_FLAG_CID_KEYED for more details.
+ *
+ * If this macro is true, all functions defined in @FT_CID_H are
+ * available.
+ *
+ */
+#define FT_IS_CID_KEYED( face ) \
+ ( !!( (face)->face_flags & FT_FACE_FLAG_CID_KEYED ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_IS_TRICKY
+ *
+ * @description:
+ * A macro that returns true whenever a face represents a 'tricky' font.
+ * See the discussion of @FT_FACE_FLAG_TRICKY for more details.
+ *
+ */
+#define FT_IS_TRICKY( face ) \
+ ( !!( (face)->face_flags & FT_FACE_FLAG_TRICKY ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_HAS_COLOR
+ *
+ * @description:
+ * A macro that returns true whenever a face object contains tables for
+ * color glyphs.
+ *
+ * @since:
+ * 2.5.1
+ *
+ */
+#define FT_HAS_COLOR( face ) \
+ ( !!( (face)->face_flags & FT_FACE_FLAG_COLOR ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_HAS_SVG
+ *
+ * @description:
+ * A macro that returns true whenever a face object contains an 'SVG~'
+ * OpenType table.
+ *
+ * @since:
+ * 2.12
+ */
+#define FT_HAS_SVG( face ) \
+ ( !!( (face)->face_flags & FT_FACE_FLAG_SVG ) )
+
+
+ /**************************************************************************
+ *
+ * @macro:
+ * FT_HAS_SBIX
+ *
+ * @description:
+ * A macro that returns true whenever a face object contains an 'sbix'
+ * OpenType table *and* outline glyphs.
+ *
+ * Currently, FreeType only supports bitmap glyphs in PNG format for this
+ * table (i.e., JPEG and TIFF formats are unsupported, as are
+ * Apple-specific formats not part of the OpenType specification).
+ *
+ * @note:
+ * For backward compatibility, a font with an 'sbix' table is treated as
+ * a bitmap-only face. Using @FT_Open_Face with
+ * @FT_PARAM_TAG_IGNORE_SBIX, an application can switch off 'sbix'
+ * handling so that the face is treated as an ordinary outline font with
+ * scalable outlines.
+ *
+ * Here is some pseudo code that roughly illustrates how to implement
+ * 'sbix' handling according to the OpenType specification.
+ *
+ * ```
+ * if ( FT_HAS_SBIX( face ) )
+ * {
+ * // open font as a scalable one without sbix handling
+ * FT_Face face2;
+ * FT_Parameter param = { FT_PARAM_TAG_IGNORE_SBIX, NULL };
+ * FT_Open_Args args = { FT_OPEN_PARAMS | ...,
+ * ...,
+ * 1, ¶m };
+ *
+ *
+ * FT_Open_Face( library, &args, 0, &face2 );
+ *
+ * available_size` as necessary into
+ * `preferred_sizes`[*]>
+ *
+ * for ( i = 0; i < face->num_fixed_sizes; i++ )
+ * {
+ * size = preferred_sizes[i].size;
+ *
+ * error = FT_Set_Pixel_Sizes( face, size, size );
+ *
+ *
+ * // check whether we have a glyph in a bitmap strike
+ * error = FT_Load_Glyph( face,
+ * glyph_index,
+ * FT_LOAD_SBITS_ONLY |
+ * FT_LOAD_BITMAP_METRICS_ONLY );
+ * if ( error == FT_Err_Invalid_Argument )
+ * continue;
+ * else if ( error )
+ *
+ * else
+ * break;
+ * }
+ *
+ * if ( i != face->num_fixed_sizes )
+ *
+ *
+ * if ( i == face->num_fixed_sizes ||
+ * FT_HAS_SBIX_OVERLAY( face ) )
+ *