diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 1f93cb2..eb65d37 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -55,7 +55,7 @@ jobs: - name: Run samples run: | - vips --version || brew install vips + vips --version || ((brew install pkgconf || brew link --overwrite pkgconf) && brew install vips) ./run_samples.sh windows-sense-check: diff --git a/README.md b/README.md index 0c5a118..860ec5a 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ repositories { } dependencies { - implementation("app.photofox.vips-ffm:vips-ffm-core:1.2.2") + implementation("app.photofox.vips-ffm:vips-ffm-core:1.3.0") } ``` When running your project you must add `--enable-native-access=ALL-UNNAMED` to your JVM runtime arguments. If you @@ -172,6 +172,12 @@ yet (which could manifest as crashes/segfaults): * `vipsffm.abinumber.glib.override`, default: `0` * `vipsffm.abinumber.gobject.override`, default: `0` +If you want to manually override the library lookup path for any of the above (for example, if you're using a platform +like Android where it's hard to set the system library path), you can do so using these system properties: +* libvips: `vipsffm.libpath.vips.override` (eg `/opt/homebrew/lib/libvips.dylib`) +* glib: `vipsffm.libpath.glib.override` +* gobject: `vipsffm.libpath.gobject.override` + ## Project goals Ideas and suggestions are welcome, but please make sure they fit in to these goals, or you have a good argument about diff --git a/core/src/main/java/app/photofox/vipsffm/VipsLibLookup.java b/core/src/main/java/app/photofox/vipsffm/VipsLibLookup.java index 92586b4..d597dc9 100644 --- a/core/src/main/java/app/photofox/vipsffm/VipsLibLookup.java +++ b/core/src/main/java/app/photofox/vipsffm/VipsLibLookup.java @@ -2,6 +2,7 @@ import java.lang.foreign.Arena; import java.lang.foreign.SymbolLookup; +import java.nio.file.Path; import java.util.List; import java.util.Optional; @@ -25,6 +26,10 @@ public static SymbolLookup buildSymbolLoader(Arena arena) { } private static SymbolLookup findVipsLoader(Arena arena) { + var overrideLookup = makeOptionalLibraryLookup("vips", arena); + if (overrideLookup.isPresent()) { + return overrideLookup.get(); + } var abiNumber = Optional.ofNullable(System.getProperty("vipsffm.abinumber.vips.override")) .orElse("42"); var names = List.of( @@ -36,6 +41,10 @@ private static SymbolLookup findVipsLoader(Arena arena) { } private static SymbolLookup findGlibLoader(Arena arena) { + var overrideLookup = makeOptionalLibraryLookup("glib", arena); + if (overrideLookup.isPresent()) { + return overrideLookup.get(); + } var abiNumber = Optional.ofNullable(System.getProperty("vipsffm.abinumber.glib.override")) .orElse("0"); var names = List.of( @@ -47,6 +56,10 @@ private static SymbolLookup findGlibLoader(Arena arena) { } private static SymbolLookup findGObjectLoader(Arena arena) { + var overrideLookup = makeOptionalLibraryLookup("gobject", arena); + if (overrideLookup.isPresent()) { + return overrideLookup.get(); + } var abiNumber = Optional.ofNullable(System.getProperty("vipsffm.abinumber.gobject.override")) .orElse("0"); var names = List.of( @@ -79,4 +92,26 @@ static Optional attemptLibraryLookup(String name, Arena arena) { return Optional.empty(); } } + + private static Optional makeOptionalLibraryLookup(String libraryName, Arena arena) { + var propertyPath = "vipsffm.libpath.%s.override".formatted(libraryName); + var overridePath = Optional.ofNullable(System.getProperty(propertyPath)); + return overridePath.map(path -> { + SymbolLookup symbolLookup; + try { + symbolLookup = SymbolLookup.libraryLookup(Path.of(path), arena); + } catch (IllegalArgumentException exception) { + throw makeOverriddenPathMissingException(libraryName, path); + } + return symbolLookup; + }); + } + + private static IllegalArgumentException makeOverriddenPathMissingException( + String libraryName, + String overridePath + ) { + var message = "path override requested for %s, but library not found at path: %s".formatted(libraryName, overridePath); + return new IllegalArgumentException(message); + } } diff --git a/docs/index.html b/docs/index.html index 2f7dcba..8631ef3 100644 --- a/docs/index.html +++ b/docs/index.html @@ -70,7 +70,7 @@

Usage

} dependencies { - implementation("app.photofox.vips-ffm:vips-ffm-core:1.2.2") + implementation("app.photofox.vips-ffm:vips-ffm-core:1.3.0") }

When running your project you must add --enable-native-access=ALL-UNNAMED to your JVM runtime arguments. If you @@ -122,8 +122,7 @@

Thumbnail sample

Vips.run { arena -> val sourceImage = VImage.newFromFile( arena, - "sample/src/main/resources/sample_images/rabbit.jpg", - VipsOption.Enum("access", VipsAccess.ACCESS_SEQUENTIAL) // example of an option + "sample/src/main/resources/sample_images/rabbit.jpg" ) val sourceWidth = sourceImage.width val sourceHeight = sourceImage.height @@ -132,9 +131,9 @@

Thumbnail sample

val outputPath = workingDirectory.resolve("rabbit_copy.jpg") sourceImage.writeToFile(outputPath.absolutePathString()) - val thumbnail = sourceImage.thumbnail( - "sample/src/main/resources/sample_images/rabbit.jpg", - 400 + val thumbnail = sourceImage.thumbnailImage( + 400, + VipsOption.Boolean("auto-rotate", true) // example of an option ) val thumbnailWidth = thumbnail.width val thumbnailHeight = thumbnail.height @@ -218,6 +217,13 @@

Native library loading

  • vipsffm.abinumber.glib.override, default: 0
  • vipsffm.abinumber.gobject.override, default: 0
  • +

    If you want to manually override the library lookup path for any of the above (for example, if you're using a platform +like Android where it's hard to set the system library path), you can do so using these system properties:

    +

    Project goals

    Ideas and suggestions are welcome, but please make sure they fit in to these goals, or you have a good argument about why a goal should change!

    diff --git a/run_samples.sh b/run_samples.sh index 7792cab..5438dd8 100755 --- a/run_samples.sh +++ b/run_samples.sh @@ -4,12 +4,15 @@ set -eou pipefail echo "building samples..." ./gradlew sample:clean sample:shadowJar +export JAVA_PATH_OPTS="" if [[ "$OSTYPE" == "darwin"* ]]; then export DYLD_LIBRARY_PATH=/opt/homebrew/lib + # this tests the library path override feature + export JAVA_PATH_OPTS="-Dvipsffm.libpath.vips.override=/opt/homebrew/lib/libvips.dylib" fi echo "running samples..." -java -jar sample/build/libs/sample-all.jar 2>&1 | tee sample_output.log +java $JAVA_PATH_OPTS -jar sample/build/libs/sample-all.jar 2>&1 | tee sample_output.log echo "checking for leaks..." if grep --quiet "objects alive:" sample_output.log; then