# media-img (C++) CMake-based **`media-img`** binary: **CLI**, **HTTP REST** (`serve`), and **line-delimited JSON IPC** (`ipc`). Image processing uses **libvips** — the same engine as **[Sharp](https://sharp.pixelplumbing.com/)** (Node.js), exposed with a similar option model. Optional **`.env`** is loaded from the working directory ([laserpants/dotenv-cpp](https://github.com/laserpants/dotenv-cpp)). - **API reference (underlying library):** [libvips `VipsImage`](https://www.libvips.org/API/current/class.Image.html) ## Prerequisites | Requirement | Notes | |-------------|--------| | CMake | ≥ 3.20 | | C++ compiler | C++17 | | **libvips** | **Required** — pkg-config (Unix) or `third_party/vips-dev-*` / `VIPS_ROOT` (Windows) | | Git | For `FetchContent` (CLI11, Asio, httplib, json, dotenv) | | Node.js | Optional — `npm run test:media` (Node 18+) | ### Installing libvips **Debian / Ubuntu** ```bash sudo apt install libvips-dev pkg-config ``` **macOS (Homebrew)** ```bash brew install vips pkg-config ``` **Windows (official dev bundle — recommended)** ```powershell npm run setup:vips ``` Downloads [build-win64-mxe `vips-dev-x64-all`](https://github.com/libvips/build-win64-mxe/releases) into `third_party/vips-dev-*`. CMake adds that path automatically; DLLs are copied to `dist/` on link. Pin the version with **`MEDIA_VIPS_VERSION`** (default `8.18.2`) if needed. Alternatively set **`VIPS_ROOT`** or **`CMAKE_PREFIX_PATH`** to a tree with `include/vips/vips.h` and `lib/libvips.lib`. ## Build ```bash cd packages/media/cpp cmake --preset release cmake --build --preset release ``` Binary: **`dist/media-img`** (`.exe` on Windows). ## Sharp-like options (`resize` / JSON) | Sharp concept | `media-img` / JSON field | Notes | |---------------|---------------------------|--------| | `resize.fit` | `fit` | `inside`, `cover`, `contain`, `fill`, `outside` | | `resize.position` | `position` | `centre`, `attention`, `entropy`, … → libvips *interesting* | | `resize.kernel` | `kernel` | `nearest`, `cubic`, `mitchell`, `lanczos2`, `lanczos3` (default) | | `jpeg|webp|… quality` | `quality` | 1–100 | | `png compression` | `png_compression` | 0–9 | | `withoutEnlargement` | `without_enlargement` | Default **true**; CLI `--allow-enlargement` flips | | EXIF orientation | `autorotate` | Default **true**; CLI `--no-autorotate` | | Strip metadata | `strip_metadata` | Default **true**; CLI `--no-strip` | | `rotate` | `rotate` | 0, 90, 180, 270 (after autorotate) | | `flip` / `flop` | `flip` / `flop` | | | Letterbox | `background` | `#rrggbb` for `contain` | **REST** `POST /v1/resize` accepts the same keys as columns in the table (plus `input`, `output` paths). **IPC** sends one JSON object per line with the same keys. ## Concurrency - **HTTP `serve`**: cpp-httplib default thread pool (`CPPHTTPLIB_THREAD_POOL_COUNT` — see upstream `httplib.h`). - **libvips**: processing is thread-safe per image; configure process-wide concurrency with `VIPS_CONCURRENCY` (or `vips_concurrency_set` in code later if needed). ## CLI overview ```bash media-img resize --help media-img serve --help media-img ipc --help ``` `kbot` subcommand forwards to **`KBOT_EXE`** (optional). ## Tests ```bash npm run test:media ``` Requires a built `dist/media-img` **linked against libvips** and fixture PNGs (`npm run generate:assets` if missing). ## License See [LICENSE](LICENSE) in this directory when present.