localtools / ai-meta-php
PHP extension for detecting, extracting, stripping, and writing AI-generation metadata in PNG/JPEG/WebP images (wraps prebuilt libai_meta).
Package info
github.com/localtools/ai-meta-php
Language:C
Type:php-ext
Ext name:ext-ai_meta
pkg:composer/localtools/ai-meta-php
Requires
- php: ^8.1
README
ai-meta-php is a traditional C PHP extension (phpize / config.m4, not FFI) for detecting, extracting, stripping, and writing AI-generation metadata declared in image files.
It wraps the ai_meta C library and links prebuilt release binaries of that library (pinned by LIBAI_META_VERSION).
- Repository: https://github.com/localtools/ai-meta-php
- License: MIT — free and open source
- PHP: 8.1+ (NTS and ZTS)
- Scope: declared metadata only — it does not analyze pixels to guess whether an undeclared image is AI-generated
Why
Generators and platforms increasingly embed provenance and generation parameters (Stable Diffusion parameters, EXIF/XMP, C2PA Content Credentials, IPTC). This extension gives PHP applications a small, dependency-light way to inspect and scrub that metadata while leaving pixel data and color profiles intact when requested.
Features
| Capability | Notes |
|---|---|
| Formats | PNG, JPEG, WebP |
| Schemes | PNG text (tEXt / iTXt / zTXt), EXIF, XMP, IPTC (JPEG), C2PA detect/strip/hints |
| Scan | Fast format + scheme bitmask + likely_ai |
| Extract | Associative field map (e.g. parameters, prompt, Seed, …) |
| Strip / write | Returns a new binary buffer; input is never mutated |
| Errors | AiMetaException with messages from ai_meta_strerror() |
C2PA signatures are not cryptographically verified (same as the C library).
Quick start
Requirements
- PHP 8.1+ with development headers (
phpize,php-config) - A C11 compiler (
cc,clang, orgcc) - zlib development headers (
zlib1g-devon Debian/Ubuntu; usually present on macOS) - A prebuilt ai_meta prefix (
include/+lib/)
Build & test
git clone https://github.com/localtools/ai-meta-php.git cd ai-meta-php ./scripts/fetch-libai-meta.sh # downloads LIBAI_META_VERSION → deps/ai_meta phpize ./configure --with-ai-meta="$PWD/deps/ai_meta" make make test
The configure step prefers lib/libai_meta.a so the resulting ai_meta.so does not need libai_meta at runtime (only zlib).
Alternative discovery:
# Unpacked release tarball / make install prefix ./configure --with-ai-meta=/path/to/ai_meta-0.1.0-linux-x86_64 # Or via pkg-config export PKG_CONFIG_PATH=/path/to/prefix/lib/pkgconfig ./configure --with-ai-meta
Load
extension=ai_meta ; or absolute path: ; extension=/absolute/path/to/modules/ai_meta.so
php -m | grep ai_meta php -r 'var_export(ai_meta_scan(file_get_contents("image.png")));'
See examples/basic.php.
Install with PIE
This extension supports PIE (PHP Installer for Extensions). Package metadata lives in composer.json (type: php-ext).
# Install PIE itself (see https://php.github.io/pie/) # Then, from source / Packagist once published: pie install localtools/ai-meta-php
Source builds need a prebuilt ai_meta library:
./scripts/fetch-libai-meta.sh pie install localtools/ai-meta-php --with-ai-meta="$PWD/deps/ai_meta" # or, if deps/ai_meta is already present in the build tree: pie install localtools/ai-meta-php
composer.json declares download-url-method: ["pre-packaged-binary", "composer-default"], so PIE prefers a matching release binary and falls back to building from source.
Publish to Packagist (submit the GitHub repo) so pie install localtools/ai-meta-php resolves without a path repository.
Prebuilt packages
Extension (this repo)
GitHub Releases attach PIE-compatible binaries (via php/pie-ext-binary-builder):
php_ai_meta-<ver>_php<X.Y>-<arch>-<os>-<libc>-<nts|zts>.zip
Local packaging after a successful make:
./scripts/package-dist.sh # human-friendly .tar.gz ./scripts/package-dist.sh --pie # PIE pre-packaged-binary .zip name
Tag a release to build and attach PIE assets automatically:
git tag v0.1.0 git push origin v0.1.0
Native library (dependency)
| Item | Location |
|---|---|
| Releases | https://github.com/localtools/ai-meta/releases |
| Pin file | LIBAI_META_VERSION |
| Fetch helper | scripts/fetch-libai-meta.sh |
This extension does not vendor or compile libai_meta sources.
PHP API
/** @return array{format: string, schemes: list<string>, likely_ai: bool} */ ai_meta_scan(string $data): array /** @return array<string, string> */ ai_meta_extract(string $data): array ai_meta_strip(string $data, int $flags = 0): string ai_meta_write(string $data, string $key, string $value): string
$bytes = file_get_contents('in.png'); $scan = ai_meta_scan($bytes); if ($scan['likely_ai']) { $fields = ai_meta_extract($bytes); // $fields['parameters'], $fields['prompt'], … $clean = ai_meta_strip( $bytes, AI_META_FLAG_STRIP_ALL_AI | AI_META_FLAG_KEEP_COLOR_PROFILE ); file_put_contents('out.png', $clean); } $written = ai_meta_write($bytes, 'parameters', "Steps: 20, Seed: 1");
On any non-OK library status, an AiMetaException (extends RuntimeException) is thrown.
Constants
| Constant | Role |
|---|---|
AI_META_FLAG_NONE |
No strip flags |
AI_META_FLAG_STRIP_PNG_TEXT / STRIP_EXIF / STRIP_XMP / STRIP_IPTC / STRIP_C2PA |
Per-scheme strip |
AI_META_FLAG_STRIP_ALL_AI |
All AI-related strip bits |
AI_META_FLAG_KEEP_COLOR_PROFILE |
Preserve ICC / color profile when possible |
AI_META_FLAG_KEEP_NON_AI_TEXT |
Keep benign PNG text when stripping |
AI_META_SCHEME_* |
Scheme bitmask values (mirror the C API) |
IDE / static-analysis stubs: stub.php, ai_meta.stub.php.
Conventions
| Topic | Rule |
|---|---|
| Errors | Throw AiMetaException; message from ai_meta_strerror() |
| Memory | Library buffers are freed inside the extension before return |
| Strip / write | Always return a new string buffer |
| Color profiles | Preserved when AI_META_FLAG_KEEP_COLOR_PROFILE is set (recommended) |
Design
- Thin PHP wrapper over the buffer-based C API
- Compiled dependency — links release artifacts of ai_meta, not a source copy
- Runtime deps — zlib (and the PHP runtime); static
libai_meta.ais preferred at link time - Portability — Linux and macOS; CI covers PHP 8.1–8.4
- Safety — malformed / truncated metadata should fail with an exception, not crash PHP
Out of scope
- Pixel / ML-based “is this AI?” detection
- Full C2PA claim verification and signing
- Lossy re-encode of image payloads (metadata containers only)
- Bundling or re-implementing the C library inside this repo
Testing
NO_INTERACTION=1 make test TESTS="tests/*.phpt"
.phpt coverage includes scan, extract, write/strip round-trip, and exception paths against small PNG fixtures under tests/fixtures/.
Project layout
composer.json PIE / Packagist metadata (type: php-ext)
ai_meta.c Extension implementation
php_ai_meta.h Version / module headers
config.m4 phpize build (links prebuilt libai_meta)
stub.php IDE stub
examples/basic.php Minimal consumer
scripts/fetch-libai-meta.sh
scripts/package-dist.sh
tests/*.phpt PHP test suite
LIBAI_META_VERSION Pinned ai_meta release
LICENSE NOTICE MIT + third-party notices
Contributing
Contributions are welcome. See CONTRIBUTING.md and our Code of Conduct.
For security issues, see SECURITY.md — please do not open public issues for vulnerabilities.
Changelog
See CHANGELOG.md.
License
This project is licensed under the MIT License — see LICENSE and NOTICE.
Copyright (c) 2026 Local Tools and ai-meta-php contributors
You may use, modify, and distribute this software under the terms of that license.
The native ai_meta library is also MIT-licensed; prebuilt binaries are obtained from its GitHub Releases.