Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ repositories {
}

dependencies {
implementation("app.photofox.vips-ffm:vips-ffm-core:1.9.5")
implementation("app.photofox.vips-ffm:vips-ffm-core:1.9.6")
}
```

Expand Down Expand Up @@ -171,14 +171,14 @@ You can find them in the [`docker_tests`](docker_tests) folder.

This library requires the `libvips`, `glib`, and `gobject` native libraries to be present in your library path:
* On macOS: `DYLD_LIBRARY_PATH` (installed with `brew install vips`)
* On Linux: `LD_LIBRARY_PATH` (installed with `apt install libvips-dev` on Debian / Ubuntu)
* On Linux: `LD_LIBRARY_PATH` (installed with `apt install libvips42` on Debian / Ubuntu)
* On Windows: `PATH`

The naming conventions of these libraries are not consistent across operating systems, so vips-ffm attempts to load each
in the following order:
* `vips`, `vips.{abiNumber}`, `libvips-{abiNumber}`
* `glib-2.0`, `glib-2.0.{abiNumber}`, `libglib-2.0-{abiNumber}`
* `gobject-2.0`, `gobject-2.0.{abiNumber}`, `libgobject-2.0-{abiNumber}`
* `vips`, `vips.{abiNumber}`, `libvips.so.{abiNumber}`, `libvips-{abiNumber}`
* `glib-2.0`, `glib-2.0.{abiNumber}`, `libglib-2.0.so.{abiNumber}`, `libglib-2.0-{abiNumber}`
* `gobject-2.0`, `gobject-2.0.{abiNumber}`, `libgobject-2.0.so.{abiNumber}`, `libgobject-2.0-{abiNumber}`

Override properties are provided to set your own "ABI number", but note that vips-ffm might not support that version
yet (which could manifest as crashes/segfaults):
Expand Down
40 changes: 26 additions & 14 deletions core/src/main/java/app/photofox/vipsffm/VipsLibLookup.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ private static SymbolLookup findVipsLoader(Arena arena) {
var abiNumber = Optional.ofNullable(System.getProperty("vipsffm.abinumber.vips.override"))
.orElse("42");
var names = List.of(
"vips", // default unix-like
"vips." + abiNumber, // some linux systems don't symlink and need abi number
"libvips-" + abiNumber // windows needs everything
new SymbolLookupSpec("vips", true), // default unix-like
new SymbolLookupSpec("vips." + abiNumber, true), // some linux systems don't symlink and need abi number
new SymbolLookupSpec("libvips.so." + abiNumber, false), // some linux runtime libs use the lib.so.abiNumber format
new SymbolLookupSpec("libvips-" + abiNumber, true) // windows needs everything
);
return findFirstSymbolLookup(arena, names);
}
Expand All @@ -48,9 +49,10 @@ private static SymbolLookup findGlibLoader(Arena arena) {
var abiNumber = Optional.ofNullable(System.getProperty("vipsffm.abinumber.glib.override"))
.orElse("0");
var names = List.of(
"glib-2.0", // default unix-like
"glib-2.0." + abiNumber, // some linux systems don't symlink and need abi number
"libglib-2.0-" + abiNumber // windows needs everything
new SymbolLookupSpec("glib-2.0", true), // default unix-like
new SymbolLookupSpec("glib-2.0." + abiNumber, true), // some linux systems don't symlink and need abi number
new SymbolLookupSpec("libglib-2.0.so." + abiNumber, false), // some linux runtime libs use the lib.so.abiNumber format
new SymbolLookupSpec("libglib-2.0-" + abiNumber, true) // windows needs everything
);
return findFirstSymbolLookup(arena, names);
}
Expand All @@ -63,30 +65,40 @@ private static SymbolLookup findGObjectLoader(Arena arena) {
var abiNumber = Optional.ofNullable(System.getProperty("vipsffm.abinumber.gobject.override"))
.orElse("0");
var names = List.of(
"gobject-2.0", // default unix-like
"gobject-2.0." + abiNumber, // some linux systems don't symlink and need abi number
"libgobject-2.0-" + abiNumber // windows needs everything
new SymbolLookupSpec("gobject-2.0", true), // default unix-like
new SymbolLookupSpec("gobject-2.0." + abiNumber, true), // some linux systems don't symlink and need abi number
new SymbolLookupSpec("libgobject-2.0.so." + abiNumber, false), // some linux runtime libs use the lib.so.abiNumber format
new SymbolLookupSpec("libgobject-2.0-" + abiNumber, true) // windows needs everything
);
return findFirstSymbolLookup(arena, names);
}

private record SymbolLookupSpec(
String name,
boolean mapToSystemName
) {}

private static SymbolLookup findFirstSymbolLookup(
Arena arena,
List<String> names
List<SymbolLookupSpec> specs
) {
for (var name : names) {
var attempt = attemptLibraryLookup(name, arena);
for (var spec : specs) {
var attempt = attemptLibraryLookup(spec.name, arena, spec.mapToSystemName);
if (attempt.isPresent()) {
return attempt.get();
}
}
return null;
}

static Optional<SymbolLookup> attemptLibraryLookup(String name, Arena arena) {
static Optional<SymbolLookup> attemptLibraryLookup(String name, Arena arena, boolean useSystemNaming) {
var libraryName = name;
if (useSystemNaming) {
libraryName = System.mapLibraryName(libraryName);
}
try {
return Optional.of(
SymbolLookup.libraryLookup(System.mapLibraryName(name), arena)
SymbolLookup.libraryLookup(libraryName, arena)
);
} catch (IllegalArgumentException _) {
return Optional.empty();
Expand Down
2 changes: 1 addition & 1 deletion docker_tests/debian-12/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ENV PATH="${JAVA_HOME}/bin:${PATH}"
COPY sample /opt/sample
COPY run_samples.sh /opt/run_samples.sh

RUN apt update && apt install --no-install-recommends --yes libvips-dev libvips-tools libjemalloc2
RUN apt update && apt install --no-install-recommends --yes libvips42 libvips-tools libjemalloc2
RUN vips --version

WORKDIR /opt
Expand Down
2 changes: 1 addition & 1 deletion docker_tests/ubuntu-2404-jemalloc/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ENV PATH="${JAVA_HOME}/bin:${PATH}"
COPY sample /opt/sample
COPY run_samples.sh /opt/run_samples.sh

RUN apt update && apt install --no-install-recommends --yes libvips-dev libvips-tools libjemalloc2
RUN apt update && apt install --no-install-recommends --yes libvips42 libvips-tools libjemalloc2
RUN ln -sT "$(readlink -e /usr/lib/*/libjemalloc.so.2)" /usr/local/lib/libjemalloc.so

RUN vips --version
Expand Down
2 changes: 1 addition & 1 deletion docker_tests/ubuntu-2404/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ENV PATH="${JAVA_HOME}/bin:${PATH}"
COPY sample /opt/sample
COPY run_samples.sh /opt/run_samples.sh

RUN apt update && apt install --no-install-recommends --yes libvips-dev libvips-tools libjemalloc2
RUN apt update && apt install --no-install-recommends --yes libvips42 libvips-tools libjemalloc2
RUN vips --version

WORKDIR /opt
Expand Down
16 changes: 8 additions & 8 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,19 @@ <h1 class="title">core API</h1>
<p>Supports a vast range of image formats, including HEIC, JXL, WebP, PNG, JPEG, and more. Pronounced &quot;vips (like zips)
eff-eff-emm&quot;. The project is relatively new, but aims to be production ready. Tested on macOS 14, Windows 11, and Linux
(Ubuntu 24.04, Debian 12.1, with and without jemalloc). Should work on any architecture you can use libvips and
Java on (arm64/amd64/etc).</p>
<p>Uses the &quot;Foreign Function &amp; Memory API&quot; (<a href="https://openjdk.org/jeps/454">JEP 454</a>), and the &quot;Class-File API&quot; (<a href="https://openjdk.org/jeps/457">JEP 457</a>) released in JDK 22.
Built in such a way that it's usually the fastest image processing library available for Java.</p>
Java on (arm64/amd64/etc). Built in such a way that it's usually the fastest image processing library available for Java,
by using the &quot;Foreign Function &amp; Memory API&quot; (<a href="https://openjdk.org/jeps/454">JEP 454</a>) and code generation.</p>
<p>Used the library? I'd love to hear from more users - let me know in <a href="https://github.com/lopcode/vips-ffm/discussions">Discussions</a>. Please also give <a href="https://github.com/lopcode/vips-ffm">the repo</a>
a star 🌟️!</p>
<p>Made in the EU 🇪🇺🇸🇪</p>
<h2 id="usage-heading">Usage</h2>
<p><code>vips-ffm</code> is available on Maven Central. To get set up with Gradle:</p>
<pre><code class="language-kotlin">repositories {
mavenCentral()
}

dependencies {
implementation(&quot;app.photofox.vips-ffm:vips-ffm-core:1.9.5&quot;)
implementation(&quot;app.photofox.vips-ffm:vips-ffm-core:1.9.6&quot;)
}
</code></pre>
<p>Figure out what you're trying to do by looking at the <a href="https://www.libvips.org/API/current/">libvips documentation</a>
Expand Down Expand Up @@ -204,15 +204,15 @@ <h2 id="native-library-loading-heading">Native library loading</h2>
<p>This library requires the <code>libvips</code>, <code>glib</code>, and <code>gobject</code> native libraries to be present in your library path:</p>
<ul>
<li>On macOS: <code>DYLD_LIBRARY_PATH</code> (installed with <code>brew install vips</code>)</li>
<li>On Linux: <code>LD_LIBRARY_PATH</code> (installed with <code>apt install libvips-dev</code> on Debian / Ubuntu)</li>
<li>On Linux: <code>LD_LIBRARY_PATH</code> (installed with <code>apt install libvips42</code> on Debian / Ubuntu)</li>
<li>On Windows: <code>PATH</code></li>
</ul>
<p>The naming conventions of these libraries are not consistent across operating systems, so vips-ffm attempts to load each
in the following order:</p>
<ul>
<li><code>vips</code>, <code>vips.{abiNumber}</code>, <code>libvips-{abiNumber}</code></li>
<li><code>glib-2.0</code>, <code>glib-2.0.{abiNumber}</code>, <code>libglib-2.0-{abiNumber}</code></li>
<li><code>gobject-2.0</code>, <code>gobject-2.0.{abiNumber}</code>, <code>libgobject-2.0-{abiNumber}</code></li>
<li><code>vips</code>, <code>vips.{abiNumber}</code>, <code>libvips.so.{abiNumber}</code>, <code>libvips-{abiNumber}</code></li>
<li><code>glib-2.0</code>, <code>glib-2.0.{abiNumber}</code>, <code>libglib-2.0.so.{abiNumber}</code>, <code>libglib-2.0-{abiNumber}</code></li>
<li><code>gobject-2.0</code>, <code>gobject-2.0.{abiNumber}</code>, <code>libgobject-2.0.so.{abiNumber}</code>, <code>libgobject-2.0-{abiNumber}</code></li>
</ul>
<p>Override properties are provided to set your own &quot;ABI number&quot;, but note that vips-ffm might not support that version
yet (which could manifest as crashes/segfaults):</p>
Expand Down
Loading