├── .editorconfig ├── .github └── workflows │ ├── after_merge.yml │ ├── build_binaries.yml │ ├── default.yml │ ├── dependencies.yml │ ├── publish_release.yml │ └── run_diffuse.yml ├── .gitignore ├── .gitmodules ├── LICENSE ├── NOTICE ├── README.md ├── build.gradle ├── gradle.properties ├── gradle ├── libs.versions.toml ├── plugins │ ├── build.gradle │ ├── settings.gradle │ └── src │ │ └── main │ │ └── kotlin │ │ └── PublishingPlugin.kt └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── libwebp-jni ├── CMakeLists.txt ├── LICENSE ├── build.yml ├── compile-all.sh ├── compile.sh ├── dockcross │ ├── dockcross-linux-arm64-lts │ ├── dockcross-linux-armv5 │ ├── dockcross-linux-armv6-lts │ ├── dockcross-linux-armv7-lts │ ├── dockcross-linux-ppc64le │ ├── dockcross-manylinux-x64 │ ├── dockcross-manylinux-x86 │ ├── dockcross-windows-static-x64 │ └── dockcross-windows-static-x86 ├── multiarch-darwin.cmake └── src │ └── main │ └── c │ ├── CMakeLists.txt │ ├── com_luciad_imageio_webp_WebP.h │ ├── com_luciad_imageio_webp_WebPDecoderOptions.h │ ├── com_luciad_imageio_webp_WebPEncoderOptions.h │ ├── jni │ ├── darwin │ │ └── jni_md.h │ ├── jni.h │ ├── unix │ │ └── jni_md.h │ └── windows │ │ └── jni_md.h │ └── webp-imageio.c ├── renovate.json ├── settings.gradle ├── testing ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── proguard │ ├── build.gradle │ ├── rules.pro │ └── src │ │ └── main │ │ ├── kotlin │ │ └── com │ │ │ └── webp │ │ │ └── imageio │ │ │ └── testing │ │ │ ├── Main.kt │ │ │ └── ResourcesLoader.kt │ │ └── resources │ │ └── lossless.webp └── settings.gradle └── webp-imageio ├── api └── webp-imageio.api ├── build.gradle └── src ├── main ├── java │ └── com │ │ └── luciad │ │ └── imageio │ │ └── webp │ │ ├── WebP.java │ │ ├── WebPDecoderOptions.java │ │ └── WebPEncoderOptions.java ├── kotlin │ └── com │ │ └── luciad │ │ └── imageio │ │ └── webp │ │ ├── CompressionType.kt │ │ ├── WebPImageReaderSpi.kt │ │ ├── WebPImageWriterSpi.kt │ │ ├── WebPReadParam.kt │ │ ├── WebPWriteParam.kt │ │ └── internal │ │ ├── JavaUtils.kt │ │ ├── NativeLoader.kt │ │ ├── OsInfo.kt │ │ ├── VP8StatusCode.kt │ │ ├── WebPReader.kt │ │ ├── WebPWrapper.kt │ │ └── WebPWriter.kt └── resources │ ├── META-INF │ ├── proguard │ │ └── web-imageio.pro │ └── services │ │ ├── javax.imageio.spi.ImageReaderSpi │ │ └── javax.imageio.spi.ImageWriterSpi │ └── native │ ├── Linux │ ├── aarch64 │ │ └── libwebp-imageio.so │ ├── arm │ │ └── libwebp-imageio.so │ ├── armv6 │ │ └── libwebp-imageio.so │ ├── armv7 │ │ └── libwebp-imageio.so │ ├── ppc64 │ │ └── libwebp-imageio.so │ ├── x86 │ │ └── libwebp-imageio.so │ └── x86_64 │ │ └── libwebp-imageio.so │ ├── Mac │ ├── aarch64 │ │ └── libwebp-imageio.dylib │ └── x86_64 │ │ └── libwebp-imageio.dylib │ └── Windows │ ├── x86 │ └── webp-imageio.dll │ └── x86_64 │ └── webp-imageio.dll └── test ├── kotlin └── com │ └── luciad │ └── imageio │ └── webp │ ├── SimpleTest.kt │ ├── WebPImageReaderSpiTest.kt │ ├── WebPTest.kt │ ├── internal │ ├── NativeLoaderTest.kt │ └── OsInfoTest.kt │ └── utils │ ├── ResourcesLoader.kt │ └── TestUtils.kt └── resources ├── lossless.webp ├── lossy.webp ├── lossy_alpha.webp ├── non_rgb_1.jpg ├── non_rgb_2.jpeg ├── test4.png ├── test4_default.webp └── test4_sharp.webp /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | insert_final_newline = true 5 | 6 | [*.{kt,kts}] 7 | max_line_length = 140 8 | indent_size = 4 9 | ij_kotlin_allow_trailing_comma = true 10 | ij_kotlin_allow_trailing_comma_on_call_site = true 11 | ij_kotlin_name_count_to_use_star_import = 999 12 | ij_kotlin_name_count_to_use_star_import_for_members = 999 13 | ktlint_code_style = intellij_idea 14 | ktlint_standard_property-naming = disabled 15 | ktlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = 2 16 | 17 | [*.java] 18 | max_line_length = 140 19 | indent_size = 2 20 | ij_continuation_indent_size = 4 21 | ij_java_names_count_to_use_import_on_demand = 999 22 | ij_java_class_count_to_use_import_on_demand = 999 23 | ij_java_packages_to_use_import_on_demand = 999 24 | ij_java_spaces_around_equality_operators = true 25 | -------------------------------------------------------------------------------- /.github/workflows/after_merge.yml: -------------------------------------------------------------------------------- 1 | name: Publish snapshots 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - main 8 | - trunk 9 | - develop 10 | - maine 11 | - mane 12 | schedule: 13 | - cron: '0 3 * * 1,4' 14 | 15 | concurrency: 16 | group: ${{ github.workflow }}-${{ github.ref }} 17 | cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} 18 | 19 | jobs: 20 | publish: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v4 24 | with: 25 | fetch-depth: 0 26 | 27 | - name: Write Gradle build properties to `~/.gradle/gradle.properties` 28 | run: | 29 | mkdir -p ~/.gradle 30 | printf "org.gradle.jvmargs=-Xmx3G -XX:+UseParallelGC\n" >> ~/.gradle/gradle.properties 31 | printf "org.gradle.vfs.watch=false\n" >> ~/.gradle/gradle.properties 32 | shell: bash 33 | 34 | - uses: gradle/actions/setup-gradle@v4 35 | 36 | - run: ./gradlew assemble 37 | 38 | - name: Unwrap GPG key 39 | if: github.event_name == 'push' 40 | env: 41 | GPG_KEY_CONTENTS: ${{ secrets.GPG_KEY_CONTENTS }} 42 | SIGNING_SECRET_KEY_RING_FILE: ${{ secrets.SIGNING_SECRET_KEY_RING_FILE }} 43 | run: sudo bash -c "echo '$GPG_KEY_CONTENTS' | base64 -d > '$SIGNING_SECRET_KEY_RING_FILE'" 44 | shell: bash 45 | 46 | - name: Publish 47 | if: github.event_name == 'push' 48 | env: 49 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 50 | OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} 51 | OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} 52 | SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }} 53 | SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} 54 | SIGNING_SECRET_KEY_RING_FILE: ${{ secrets.SIGNING_SECRET_KEY_RING_FILE }} 55 | run: ./gradlew publishMavenJavaPublicationToGithubRepository 56 | 57 | - uses: actions/cache@v4 58 | name: Upload base (release) 59 | with: 60 | path: diffuse-source-file 61 | key: diffuse-${{ github.sha }} 62 | 63 | - run: find . -regex ".*webp-imageio/build/libs/webp-imageio-[0-9SNAPSHOT\.-]*\.jar" -print | xargs -n 1 -I % cp % diffuse-source-file 64 | shell: bash 65 | 66 | - name: Check size 67 | run: du -h diffuse-source-file 68 | shell: bash 69 | -------------------------------------------------------------------------------- /.github/workflows/build_binaries.yml: -------------------------------------------------------------------------------- 1 | name: Build binaries 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | libwebp_ref: 7 | description: 'libwebp tag to checkout (i.e. v1.2.3)' 8 | required: true 9 | type: string 10 | 11 | concurrency: 12 | group: ${{ github.workflow }}-${{ github.ref }} 13 | cancel-in-progress: true 14 | 15 | jobs: 16 | build-binaries: 17 | runs-on: ubuntu-latest 18 | steps: 19 | # From 20 | - name: Free up disk space 21 | run: | 22 | sudo rm -rf /usr/share/dotnet 23 | sudo rm -rf /opt/ghc 24 | sudo rm -rf "/usr/local/share/boost" 25 | sudo rm -rf "$AGENT_TOOLSDIRECTORY" 26 | 27 | - uses: actions/checkout@v4 28 | with: 29 | fetch-depth: 0 30 | submodules: true 31 | 32 | - run: git -C libwebp-jni/libwebp checkout ${{ inputs.libwebp_ref }} 33 | 34 | - run: cd libwebp-jni && ./compile-all.sh 35 | 36 | - run: git status 37 | 38 | - uses: peter-evans/create-pull-request@v7 39 | with: 40 | token: ${{ secrets.PUBLIC_REPO_TOKEN }} 41 | commit-message: "Build libwebp binaries. version ${{ inputs.libwebp_ref }}" 42 | committer: GitHub 43 | author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> 44 | delete-branch: true 45 | title: "Build libwebp binaries, version `${{ inputs.libwebp_ref }}`" 46 | body: | 47 | Build libwebp binaries, version [${{ inputs.libwebp_ref }}](https://chromium.googlesource.com/webm/libwebp/+/refs/tags/${{ inputs.libwebp_ref }}) 48 | -------------------------------------------------------------------------------- /.github/workflows/default.yml: -------------------------------------------------------------------------------- 1 | name: Build project 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | - main 9 | - trunk 10 | - develop 11 | - maine 12 | - mane 13 | schedule: 14 | - cron: '0 3 * * 1,4' 15 | 16 | concurrency: 17 | group: ${{ github.workflow }}-${{ github.ref }} 18 | cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} 19 | 20 | jobs: 21 | build: 22 | runs-on: ${{ matrix.os }} 23 | strategy: 24 | fail-fast: false 25 | matrix: 26 | os: [ ubuntu-latest, windows-latest, macos-latest ] 27 | steps: 28 | - uses: actions/checkout@v4 29 | with: 30 | fetch-depth: 0 31 | 32 | - name: Write Gradle build properties to `~/.gradle/gradle.properties` 33 | run: | 34 | mkdir -p ~/.gradle 35 | printf "org.gradle.jvmargs=-Xmx3G -XX:+UseParallelGC\n" >> ~/.gradle/gradle.properties 36 | printf "org.gradle.vfs.watch=false\n" >> ~/.gradle/gradle.properties 37 | shell: bash 38 | 39 | - uses: actions/setup-java@v4 40 | with: 41 | distribution: 'temurin' 42 | java-version: | 43 | 11 44 | 17 45 | 21 46 | 47 | - uses: gradle/actions/wrapper-validation@v4 48 | 49 | - uses: gradle/actions/setup-gradle@v4 50 | 51 | - run: ./gradlew projectCodestyle --scan 52 | 53 | - run: ./gradlew assemble check --scan 54 | 55 | - run: ./gradlew projectCoverage --scan 56 | 57 | - run: ./gradlew publishToMavenLocal 58 | 59 | - run: git diff --exit-code 60 | 61 | - uses: actions/upload-artifact@v4 62 | if: ${{ always() }} 63 | with: 64 | name: test-results-${{ matrix.os }} 65 | path: "${{ github.workspace }}/**/build/reports" 66 | 67 | test-obfuscation: 68 | runs-on: ubuntu-latest 69 | steps: 70 | - uses: actions/checkout@v4 71 | with: 72 | fetch-depth: 0 73 | 74 | - name: Write Gradle build properties to `~/.gradle/gradle.properties` 75 | run: | 76 | mkdir -p ~/.gradle 77 | printf "org.gradle.jvmargs=-Xmx3G -XX:+UseParallelGC\n" >> ~/.gradle/gradle.properties 78 | printf "org.gradle.vfs.watch=false\n" >> ~/.gradle/gradle.properties 79 | shell: bash 80 | 81 | - uses: actions/setup-java@v4 82 | with: 83 | distribution: 'temurin' 84 | java-version: 21 85 | 86 | - uses: gradle/actions/setup-gradle@v4 87 | 88 | - run: cd testing && ./gradlew assemble 89 | 90 | - run: java -jar testing/proguard/build/libs/proguard-r8.jar 91 | -------------------------------------------------------------------------------- /.github/workflows/dependencies.yml: -------------------------------------------------------------------------------- 1 | name: Generate dependency diff 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | - main 8 | - trunk 9 | - develop 10 | - maine 11 | - mane 12 | 13 | concurrency: 14 | group: ${{ github.workflow }}-${{ github.ref }} 15 | cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} 16 | 17 | jobs: 18 | generate-diff: 19 | env: 20 | github_token: ${{ secrets.GITHUB_TOKEN }} 21 | runs-on: ubuntu-latest 22 | 23 | steps: 24 | - uses: actions/checkout@v4 25 | with: 26 | fetch-depth: 0 27 | 28 | - name: Write Gradle build properties to `~/.gradle/gradle.properties` 29 | run: | 30 | mkdir -p ~/.gradle 31 | printf "org.gradle.jvmargs=-Xmx3G -XX:+UseParallelGC\n" >> ~/.gradle/gradle.properties 32 | printf "org.gradle.vfs.watch=false\n" >> ~/.gradle/gradle.properties 33 | shell: bash 34 | 35 | - uses: actions/setup-java@v4 36 | with: 37 | distribution: 'temurin' 38 | java-version: 21 39 | 40 | - uses: gradle/actions/setup-gradle@v4 41 | 42 | - run: ./gradlew assemble -m 43 | 44 | - id: dependency-diff 45 | name: Generate dependency diff 46 | uses: usefulness/dependency-tree-diff-action@v2 47 | with: 48 | project: 'webp-imageio' 49 | configuration: runtimeClasspath 50 | 51 | - uses: peter-evans/find-comment@v3 52 | id: find_comment 53 | with: 54 | issue-number: ${{ github.event.pull_request.number }} 55 | body-includes: Dependency diff 56 | 57 | - uses: peter-evans/create-or-update-comment@v4 58 | if: ${{ steps.dependency-diff.outputs.text-diff != null || steps.find_comment.outputs.comment-id != null }} 59 | with: 60 | body: | 61 | Dependency diff: 62 | ```diff 63 | ${{ steps.dependency-diff.outputs.text-diff }} 64 | ``` 65 | edit-mode: replace 66 | comment-id: ${{ steps.find_comment.outputs.comment-id }} 67 | issue-number: ${{ github.event.pull_request.number }} 68 | token: ${{ secrets.GITHUB_TOKEN }} 69 | -------------------------------------------------------------------------------- /.github/workflows/publish_release.yml: -------------------------------------------------------------------------------- 1 | name: Publish Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | build: 10 | env: 11 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 12 | OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME_FOR_COM_GITHUB }} 13 | OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD_FOR_COM_GITHUB }} 14 | SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }} 15 | SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} 16 | SIGNING_SECRET_KEY_RING_FILE: ${{ secrets.SIGNING_SECRET_KEY_RING_FILE }} 17 | 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v4 21 | with: 22 | fetch-depth: 0 23 | 24 | - name: Write Gradle build properties to `~/.gradle/gradle.properties` 25 | run: | 26 | mkdir -p ~/.gradle 27 | printf "org.gradle.jvmargs=-Xmx3G -XX:+UseParallelGC\n" >> ~/.gradle/gradle.properties 28 | printf "org.gradle.vfs.watch=false\n" >> ~/.gradle/gradle.properties 29 | shell: bash 30 | 31 | - uses: actions/setup-java@v4 32 | with: 33 | distribution: 'temurin' 34 | java-version: 21 35 | 36 | - uses: gradle/actions/setup-gradle@v4 37 | 38 | - run: ./gradlew assemble 39 | 40 | - name: Unwrap GPG key 41 | env: 42 | GPG_KEY_CONTENTS: ${{ secrets.GPG_KEY_CONTENTS }} 43 | SIGNING_SECRET_KEY_RING_FILE: ${{ secrets.SIGNING_SECRET_KEY_RING_FILE }} 44 | run: sudo bash -c "echo '$GPG_KEY_CONTENTS' | base64 -d > '$SIGNING_SECRET_KEY_RING_FILE'" 45 | 46 | - name: Publish to Maven Central 47 | run: ./gradlew publishMavenJavaPublicationToMavenCentralRepository 48 | 49 | - name: Publish to Github Package Registry 50 | run: ./gradlew publishMavenJavaPublicationToGithubRepository 51 | -------------------------------------------------------------------------------- /.github/workflows/run_diffuse.yml: -------------------------------------------------------------------------------- 1 | name: Diffuse 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | - main 8 | - trunk 9 | - develop 10 | - maine 11 | - mane 12 | 13 | concurrency: 14 | group: ${{ github.workflow }}-${{ github.ref }} 15 | cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} 16 | 17 | permissions: 18 | contents: read 19 | pull-requests: write 20 | 21 | jobs: 22 | run-diffuse: 23 | env: 24 | github_token: ${{ secrets.GITHUB_TOKEN }} 25 | runs-on: ubuntu-latest 26 | 27 | steps: 28 | - uses: actions/checkout@v4 29 | with: 30 | fetch-depth: 0 31 | 32 | - name: Write Gradle build properties to `~/.gradle/gradle.properties` 33 | run: | 34 | mkdir -p ~/.gradle 35 | printf "org.gradle.jvmargs=-Xmx3G -XX:+UseParallelGC\n" >> ~/.gradle/gradle.properties 36 | printf "org.gradle.vfs.watch=false\n" >> ~/.gradle/gradle.properties 37 | shell: bash 38 | 39 | - uses: actions/setup-java@v4 40 | with: 41 | distribution: 'temurin' 42 | java-version: 21 43 | 44 | - uses: gradle/actions/setup-gradle@v4 45 | 46 | - run: ./gradlew assemble 47 | 48 | - run: find . -regex ".*webp-imageio/build/libs/webp-imageio-[0-9SNAPSHOT\.-]*\.jar" -print | xargs -n 1 -I % cp % pull-request-artifact.jar 49 | shell: bash 50 | 51 | - name: Check size 52 | run: du -h pull-request-artifact.jar 53 | shell: bash 54 | 55 | - uses: actions/cache@v4 56 | name: Download base 57 | with: 58 | path: | 59 | diffuse-source-file 60 | key: diffuse-${{ github.event.pull_request.base.sha }} 61 | restore-keys: diffuse-${{ github.event.pull_request.base.sha }} 62 | 63 | - id: diffuse 64 | uses: usefulness/diffuse-action@v1 65 | with: 66 | old-file-path: diffuse-source-file 67 | new-file-path: pull-request-artifact.jar 68 | 69 | - uses: peter-evans/find-comment@v3 70 | id: find_comment 71 | with: 72 | issue-number: ${{ github.event.pull_request.number }} 73 | body-includes: Diffuse output 74 | 75 | - uses: peter-evans/create-or-update-comment@v4 76 | if: ${{ steps.diffuse.outputs.diff-gh-comment != null || steps.find_comment.outputs.comment-id != null }} 77 | with: 78 | body: | 79 | ### Jar size: 80 | Jar size change: ${{ steps.diffuse.outputs.size-diff-comment_style_1 }} 81 | ### Diffuse output: 82 | ${{ steps.diffuse.outputs.diff-gh-comment }} 83 | edit-mode: replace 84 | comment-id: ${{ steps.find_comment.outputs.comment-id }} 85 | issue-number: ${{ github.event.pull_request.number }} 86 | token: ${{ secrets.GITHUB_TOKEN }} 87 | 88 | - uses: actions/upload-artifact@v4 89 | with: 90 | name: diffuse-output 91 | path: ${{ steps.diffuse.outputs.diff-file }} 92 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | .idea 3 | .ideatmp 4 | out 5 | build 6 | cmake-build-* 7 | .gradle 8 | *.iml 9 | *.imltmp 10 | .DS_Store 11 | target 12 | .kotlin 13 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libwebp-jni/libwebp"] 2 | path = libwebp-jni/libwebp 3 | url = https://chromium.googlesource.com/webm/libwebp 4 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Luciad WebP Image I/O support library 2 | Copyright 2016 Luciad 3 | 4 | This product includes software developed at 5 | Luciad (http://www.luciad.com). 6 | 7 | Credits to Gauthier Roebroeck for creating necessary setup to build native libwebp binaries 8 | Copyright 2022 Mateusz Kwieciński 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # webp-imageio 2 | 3 | [![Build](https://github.com/usefulness/webp-imageio/actions/workflows/after_merge.yml/badge.svg?branch=master)](https://github.com/usefulness/webp-imageio/actions/workflows/after_merge.yml) 4 | ![Maven Central](https://img.shields.io/maven-central/v/com.github.usefulness/webp-imageio) 5 | ![Static Badge](https://img.shields.io/badge/java_compatibility-11-blue) 6 | 7 | ## Description 8 | 9 | [Java Image I/O](https://docs.oracle.com/en/java/javase/20/docs/api/java.desktop/javax/imageio/package-summary.html) reader and writer for the 10 | [Google WebP](https://developers.google.com/speed/webp/) image format. 11 | 12 | ### Highlights: 13 | - `macos-aarch64` architecture support (ARM chipsets from Apple, M1, M2) ✅ 14 | - Sharp YUV option support ✅ 15 | - Written in Kotlin, compatible with Java 16 | 17 | ### Supported platforms 18 | 19 | See the [full list](https://github.com/usefulness/webp-imageio/tree/master/webp-imageio/src/main/resources/native) of supported platforms 20 | 21 | ## Usage 22 | 23 | 1. Add dependency `com.github.usefulness:webp-imageio` to your application 24 | ```groovy 25 | dependencies { 26 | runtimeOnly("com.github.usefulness:webp-imageio:x.y.z") 27 | } 28 | ``` 29 | 2. The WebP reader and writer can be used like any other Image I/O reader and writer. 30 | 31 | ### Decoding 32 | 33 | WebP images can be decoded using default settings as follows. 34 | 35 |
36 | Kotlin 37 | 38 | ```kotlin 39 | val image = ImageIO.read(File("input.webp")) 40 | ``` 41 |
42 | 43 |
44 | Java 45 | 46 | ```java 47 | BufferedImage image = ImageIO.read(new File("input.webp")); 48 | ``` 49 |
50 | 51 | To customize the WebP decoder settings you need to create instances of ImageReader and WebPReadParam. 52 | 53 |
54 | Kotlin 55 | 56 | ```kotlin 57 | // Obtain a WebP ImageReader instance 58 | val reader = ImageIO.getImageReadersByMIMEType("image/webp").next() 59 | 60 | // Configure decoding parameters 61 | val readParam = WebPReadParam().apply { 62 | bypassFiltering = true 63 | } 64 | 65 | // Configure the input on the ImageReader 66 | reader.setInput(FileImageInputStream(File("input.webp"))) 67 | 68 | // Decode the image 69 | val image = reader.read(0, readParam) 70 | ``` 71 |
72 | 73 |
74 | Java 75 | 76 | ```java 77 | // Obtain a WebP ImageReader instance 78 | ImageReader reader = ImageIO.getImageReadersByMIMEType("image/webp").next(); 79 | 80 | // Configure decoding parameters 81 | WebPReadParam readParam = new WebPReadParam(); 82 | readParam.setBypassFiltering(true); 83 | 84 | // Configure the input on the ImageReader 85 | reader.setInput(new FileImageInputStream(new File("input.webp"))); 86 | 87 | // Decode the image 88 | BufferedImage image = reader.read(0, readParam); 89 | ``` 90 |
91 | 92 | ### Encoding 93 | 94 | Encoding is done in a similar way to decoding. 95 | 96 | You can either use the Image I/O convenience methods to encode using default settings. 97 | 98 |
99 | Kotlin 100 | 101 | ```kotlin 102 | // Obtain an image to encode from somewhere 103 | val image = ImageIO.read(File("input.png")) 104 | 105 | // Encode it as webp using default settings 106 | ImageIO.write(image, "webp", File("output.webp")) 107 | ``` 108 |
109 | 110 |
111 | Java 112 | 113 | ```java 114 | // Obtain an image to encode from somewhere 115 | BufferedImage image = ImageIO.read(new File("input.png")); 116 | 117 | // Encode it as webp using default settings 118 | ImageIO.write(image, "webp", new File("output.webp")); 119 | ``` 120 |
121 | 122 | Or you can create an instance of ImageWriter and WebPWriteParam to use custom settings. 123 | 124 |
125 | Kotlin 126 | 127 | ```kotlin 128 | // Obtain an image to encode from somewhere 129 | val image = ImageIO.read(File("input.png")) 130 | 131 | // Obtain a WebP ImageWriter instance 132 | val writer = ImageIO.getImageWritersByMIMEType("image/webp").next() 133 | 134 | // Configure encoding parameters 135 | val writeParam = (writer.defaultWriteParam as WebPWriteParam).apply { 136 | compressionType = CompressionType.Lossy 137 | alphaCompressionAlgorithm = 1 138 | useSharpYUV = true 139 | } 140 | 141 | // Configure the output on the ImageWriter 142 | writer.output = FileImageOutputStream(File("output.webp")) 143 | 144 | // Encode 145 | writer.write(null, IIOImage(image, null, null), writeParam) 146 | ``` 147 |
148 | 149 |
150 | Java 151 | 152 | ```java 153 | // Obtain an image to encode from somewhere 154 | BufferedImage image = ImageIO.read(new File("input.png")); 155 | 156 | // Obtain a WebP ImageWriter instance 157 | ImageWriter writer = ImageIO.getImageWritersByMIMEType("image/webp").next(); 158 | 159 | // Configure encoding parameters 160 | WebPWriteParam writeParam = ((WebPWriteParam) writer.getDefaultWriteParam()); 161 | writeParam.setCompressionType(CompressionType.Lossy); 162 | writeParam.setAlphaCompressionAlgorithm(3); 163 | writeParam.setUseSharpYUV(true); 164 | 165 | // Configure the output on the ImageWriter 166 | writer.setOutput(new FileImageOutputStream(new File("output.webp"))); 167 | 168 | // Encode 169 | writer.write(null, new IIOImage(image, null, null), writeParam); 170 | ``` 171 |
172 | 173 | ## R8 / ProGuard 174 | If you are using R8 the shrinking and obfuscation rules are included automatically. 175 | 176 | ProGuard users must manually add the options from [webp-imageio.pro](https://github.com/usefulness/webp-imageio/blob/master/webp-imageio/src/main/resources/META-INF/proguard/web-imageio.pro) 177 | 178 | ## License 179 | 180 | `webp-imageio` is distributed under the [Apache Software License](https://www.apache.org/licenses/LICENSE-2.0) version 181 | 2.0. 182 | `libwebp` binaries are distributed under the [Following License](https://chromium.googlesource.com/webm/libwebp/+/refs/tags/v1.3.0/COPYING) 183 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.starter.config) 3 | alias(libs.plugins.starter.versioning) 4 | alias(libs.plugins.osacky.doctor) 5 | } 6 | 7 | commonConfig { 8 | javaFilesAllowed true 9 | javaVersion = JavaVersion.VERSION_1_9 10 | } 11 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.parallel=true 2 | org.gradle.caching=true 3 | org.gradle.configuration-cache=true 4 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | gradle-starter = "0.84.1" 3 | gradle-doctor = "0.11.0" 4 | gradle-johnrengelman-shadow = "8.1.1" 5 | maven-junit = "5.13.1" 6 | maven-assertj = "3.27.3" 7 | maven-binarycompatiblity = "0.17.0" 8 | maven-dokka = "2.0.0" 9 | google-r8 = "8.7.18" 10 | 11 | [libraries] 12 | junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "maven-junit" } 13 | junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "maven-junit" } 14 | junit-jupiter-platform = { module = "org.junit.platform:junit-platform-launcher" } 15 | assertj-core = { module = "org.assertj:assertj-core", version.ref = "maven-assertj" } 16 | jetbrains-dokka = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "maven-dokka" } 17 | r8-core = { module = "com.android.tools:r8", version.ref = "google-r8" } 18 | 19 | [plugins] 20 | starter-config = { id = "com.starter.config", version.ref = "gradle-starter" } 21 | starter-versioning = { id = "com.starter.versioning", version.ref = "gradle-starter" } 22 | starter-library-kotlin = { id = "com.starter.library.kotlin", version.ref = "gradle-starter" } 23 | osacky-doctor = { id = "com.osacky.doctor", version.ref = "gradle-doctor" } 24 | johnrengelman-shadow = { id = "com.github.johnrengelman.shadow", version.ref = "gradle-johnrengelman-shadow" } 25 | kotlinx-binarycompatibility = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "maven-binarycompatiblity" } 26 | -------------------------------------------------------------------------------- /gradle/plugins/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("java-gradle-plugin") 3 | alias(libs.plugins.starter.library.kotlin) 4 | alias(libs.plugins.osacky.doctor) 5 | } 6 | 7 | kotlin { 8 | jvmToolchain(21) 9 | } 10 | 11 | gradlePlugin { 12 | plugins { 13 | publishingPlugin { 14 | id = 'com.starter.publishing' 15 | implementationClass = 'PublishingPlugin' 16 | } 17 | } 18 | } 19 | 20 | dependencies { 21 | implementation(libs.jetbrains.dokka) 22 | } 23 | -------------------------------------------------------------------------------- /gradle/plugins/settings.gradle: -------------------------------------------------------------------------------- 1 | import org.gradle.api.initialization.resolve.RepositoriesMode 2 | 3 | pluginManagement { 4 | dependencyResolutionManagement { 5 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 6 | repositories { 7 | mavenCentral() 8 | gradlePluginPortal() 9 | } 10 | } 11 | } 12 | 13 | plugins { 14 | id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" 15 | } 16 | 17 | dependencyResolutionManagement { 18 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 19 | repositories { 20 | google() 21 | mavenCentral() 22 | } 23 | versionCatalogs { 24 | create("libs") { 25 | from(files("../libs.versions.toml")) 26 | } 27 | } 28 | } 29 | 30 | rootProject.name = "plugins" 31 | -------------------------------------------------------------------------------- /gradle/plugins/src/main/kotlin/PublishingPlugin.kt: -------------------------------------------------------------------------------- 1 | import org.gradle.api.Plugin 2 | import org.gradle.api.Project 3 | import org.gradle.api.plugins.ExtensionContainer 4 | import org.gradle.api.plugins.JavaPluginExtension 5 | import org.gradle.api.publish.PublishingExtension 6 | import org.gradle.api.publish.maven.MavenPublication 7 | import org.gradle.jvm.tasks.Jar 8 | import org.gradle.language.jvm.tasks.ProcessResources 9 | import org.gradle.plugins.signing.SigningExtension 10 | import org.jetbrains.dokka.gradle.DokkaTask 11 | 12 | class PublishingPlugin : Plugin { 13 | 14 | override fun apply(target: Project) = with(target) { 15 | pluginManager.apply("maven-publish") 16 | if (findConfig("SIGNING_PASSWORD").isNotEmpty()) { 17 | pluginManager.apply("signing") 18 | } 19 | 20 | extensions.configure { 21 | withSourcesJar() 22 | withJavadocJar() 23 | } 24 | 25 | pluginManager.withPlugin("org.jetbrains.kotlin.jvm") { 26 | pluginManager.apply("org.jetbrains.dokka") 27 | 28 | tasks.withType(DokkaTask::class.java).configureEach { dokkaTask -> 29 | dokkaTask.notCompatibleWithConfigurationCache("https://github.com/Kotlin/dokka/issues/1217") 30 | } 31 | tasks.named("javadocJar", Jar::class.java) { javadocJar -> 32 | javadocJar.from(tasks.named("dokkaJavadoc")) 33 | } 34 | tasks.named("processResources", ProcessResources::class.java) { processResources -> 35 | processResources.from(rootProject.file("NOTICE")) 36 | processResources.from(rootProject.file("LICENSE")) 37 | } 38 | } 39 | 40 | extensions.configure { 41 | with(repositories) { 42 | maven { maven -> 43 | maven.name = "github" 44 | maven.setUrl("https://maven.pkg.github.com/usefulness/webp-imageio") 45 | with(maven.credentials) { 46 | username = "usefulness" 47 | password = findConfig("GITHUB_TOKEN") 48 | } 49 | } 50 | maven { maven -> 51 | maven.name = "mavenCentral" 52 | maven.setUrl("https://oss.sonatype.org/service/local/staging/deploy/maven2/") 53 | maven.mavenContent { it.releasesOnly() } 54 | with(maven.credentials) { 55 | username = findConfig("OSSRH_USERNAME") 56 | password = findConfig("OSSRH_PASSWORD") 57 | } 58 | } 59 | maven { maven -> 60 | maven.name = "mavenCentralSnapshot" 61 | maven.setUrl("https://oss.sonatype.org/content/repositories/snapshots") 62 | maven.mavenContent { it.snapshotsOnly() } 63 | with(maven.credentials) { 64 | username = findConfig("OSSRH_USERNAME") 65 | password = findConfig("OSSRH_PASSWORD") 66 | } 67 | } 68 | } 69 | with(publications) { 70 | register("mavenJava", MavenPublication::class.java) { publication -> 71 | publication.from(components.getByName("java")) 72 | publication.pom { pom -> 73 | pom.name.set("${project.group}:${project.name}") 74 | pom.description.set("Java ImageIO WebP support") 75 | pom.url.set("https://github.com/usefulness/webp-imageio") 76 | pom.licenses { licenses -> 77 | licenses.license { license -> 78 | license.name.set("Apache-2.0") 79 | license.url.set("https://github.com/usefulness/webp-imageio/blob/master/LICENSE") 80 | } 81 | } 82 | pom.developers { developers -> 83 | developers.developer { developer -> 84 | developer.id.set("mateuszkwiecinski") 85 | developer.name.set("Mateusz Kwiecinski") 86 | developer.email.set("36954793+mateuszkwiecinski@users.noreply.github.com") 87 | } 88 | } 89 | pom.scm { scm -> 90 | scm.connection.set("scm:git:github.com/usefulness/webp-imageio.git") 91 | scm.developerConnection.set("scm:git:ssh://github.com/usefulness/webp-imageio.git") 92 | scm.url.set("https://github.com/usefulness/webp-imageio/tree/master") 93 | } 94 | } 95 | } 96 | } 97 | } 98 | pluginManager.withPlugin("signing") { 99 | with(extensions.extraProperties) { 100 | set("signing.keyId", findConfig("SIGNING_KEY_ID")) 101 | set("signing.password", findConfig("SIGNING_PASSWORD")) 102 | set("signing.secretKeyRingFile", findConfig("SIGNING_SECRET_KEY_RING_FILE")) 103 | } 104 | 105 | extensions.configure("signing") { signing -> 106 | signing.sign(extensions.getByType(PublishingExtension::class.java).publications) 107 | } 108 | } 109 | } 110 | 111 | private inline fun ExtensionContainer.configure(crossinline receiver: T.() -> Unit) { 112 | configure(T::class.java) { receiver(it) } 113 | } 114 | } 115 | 116 | private fun Project.findConfig(key: String): String { 117 | return findProperty(key)?.toString() ?: System.getenv(key) ?: "" 118 | } 119 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # SPDX-License-Identifier: Apache-2.0 19 | # 20 | 21 | ############################################################################## 22 | # 23 | # Gradle start up script for POSIX generated by Gradle. 24 | # 25 | # Important for running: 26 | # 27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 28 | # noncompliant, but you have some other compliant shell such as ksh or 29 | # bash, then to run this script, type that shell name before the whole 30 | # command line, like: 31 | # 32 | # ksh Gradle 33 | # 34 | # Busybox and similar reduced shells will NOT work, because this script 35 | # requires all of these POSIX shell features: 36 | # * functions; 37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 39 | # * compound commands having a testable exit status, especially «case»; 40 | # * various built-in commands including «command», «set», and «ulimit». 41 | # 42 | # Important for patching: 43 | # 44 | # (2) This script targets any POSIX shell, so it avoids extensions provided 45 | # by Bash, Ksh, etc; in particular arrays are avoided. 46 | # 47 | # The "traditional" practice of packing multiple parameters into a 48 | # space-separated string is a well documented source of bugs and security 49 | # problems, so this is (mostly) avoided, by progressively accumulating 50 | # options in "$@", and eventually passing that to Java. 51 | # 52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 54 | # see the in-line comments for details. 55 | # 56 | # There are tweaks for specific operating systems such as AIX, CygWin, 57 | # Darwin, MinGW, and NonStop. 58 | # 59 | # (3) This script is generated from the Groovy template 60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 61 | # within the Gradle project. 62 | # 63 | # You can find Gradle at https://github.com/gradle/gradle/. 64 | # 65 | ############################################################################## 66 | 67 | # Attempt to set APP_HOME 68 | 69 | # Resolve links: $0 may be a link 70 | app_path=$0 71 | 72 | # Need this for daisy-chained symlinks. 73 | while 74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 75 | [ -h "$app_path" ] 76 | do 77 | ls=$( ls -ld "$app_path" ) 78 | link=${ls#*' -> '} 79 | case $link in #( 80 | /*) app_path=$link ;; #( 81 | *) app_path=$APP_HOME$link ;; 82 | esac 83 | done 84 | 85 | # This is normally unused 86 | # shellcheck disable=SC2034 87 | APP_BASE_NAME=${0##*/} 88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s 90 | ' "$PWD" ) || exit 91 | 92 | # Use the maximum available, or set MAX_FD != -1 to use that value. 93 | MAX_FD=maximum 94 | 95 | warn () { 96 | echo "$*" 97 | } >&2 98 | 99 | die () { 100 | echo 101 | echo "$*" 102 | echo 103 | exit 1 104 | } >&2 105 | 106 | # OS specific support (must be 'true' or 'false'). 107 | cygwin=false 108 | msys=false 109 | darwin=false 110 | nonstop=false 111 | case "$( uname )" in #( 112 | CYGWIN* ) cygwin=true ;; #( 113 | Darwin* ) darwin=true ;; #( 114 | MSYS* | MINGW* ) msys=true ;; #( 115 | NONSTOP* ) nonstop=true ;; 116 | esac 117 | 118 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 119 | 120 | 121 | # Determine the Java command to use to start the JVM. 122 | if [ -n "$JAVA_HOME" ] ; then 123 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 124 | # IBM's JDK on AIX uses strange locations for the executables 125 | JAVACMD=$JAVA_HOME/jre/sh/java 126 | else 127 | JAVACMD=$JAVA_HOME/bin/java 128 | fi 129 | if [ ! -x "$JAVACMD" ] ; then 130 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 131 | 132 | Please set the JAVA_HOME variable in your environment to match the 133 | location of your Java installation." 134 | fi 135 | else 136 | JAVACMD=java 137 | if ! command -v java >/dev/null 2>&1 138 | then 139 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 140 | 141 | Please set the JAVA_HOME variable in your environment to match the 142 | location of your Java installation." 143 | fi 144 | fi 145 | 146 | # Increase the maximum file descriptors if we can. 147 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 148 | case $MAX_FD in #( 149 | max*) 150 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 151 | # shellcheck disable=SC2039,SC3045 152 | MAX_FD=$( ulimit -H -n ) || 153 | warn "Could not query maximum file descriptor limit" 154 | esac 155 | case $MAX_FD in #( 156 | '' | soft) :;; #( 157 | *) 158 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 159 | # shellcheck disable=SC2039,SC3045 160 | ulimit -n "$MAX_FD" || 161 | warn "Could not set maximum file descriptor limit to $MAX_FD" 162 | esac 163 | fi 164 | 165 | # Collect all arguments for the java command, stacking in reverse order: 166 | # * args from the command line 167 | # * the main class name 168 | # * -classpath 169 | # * -D...appname settings 170 | # * --module-path (only if needed) 171 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 172 | 173 | # For Cygwin or MSYS, switch paths to Windows format before running java 174 | if "$cygwin" || "$msys" ; then 175 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 176 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 177 | 178 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 179 | 180 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 181 | for arg do 182 | if 183 | case $arg in #( 184 | -*) false ;; # don't mess with options #( 185 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 186 | [ -e "$t" ] ;; #( 187 | *) false ;; 188 | esac 189 | then 190 | arg=$( cygpath --path --ignore --mixed "$arg" ) 191 | fi 192 | # Roll the args list around exactly as many times as the number of 193 | # args, so each arg winds up back in the position where it started, but 194 | # possibly modified. 195 | # 196 | # NB: a `for` loop captures its iteration list before it begins, so 197 | # changing the positional parameters here affects neither the number of 198 | # iterations, nor the values presented in `arg`. 199 | shift # remove old arg 200 | set -- "$@" "$arg" # push replacement arg 201 | done 202 | fi 203 | 204 | 205 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 206 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 207 | 208 | # Collect all arguments for the java command: 209 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, 210 | # and any embedded shellness will be escaped. 211 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be 212 | # treated as '${Hostname}' itself on the command line. 213 | 214 | set -- \ 215 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 216 | -classpath "$CLASSPATH" \ 217 | org.gradle.wrapper.GradleWrapperMain \ 218 | "$@" 219 | 220 | # Stop when "xargs" is not available. 221 | if ! command -v xargs >/dev/null 2>&1 222 | then 223 | die "xargs is not available" 224 | fi 225 | 226 | # Use "xargs" to parse quoted args. 227 | # 228 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 229 | # 230 | # In Bash we could simply go: 231 | # 232 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 233 | # set -- "${ARGS[@]}" "$@" 234 | # 235 | # but POSIX shell has neither arrays nor command substitution, so instead we 236 | # post-process each arg (as a line of input to sed) to backslash-escape any 237 | # character that might be a shell metacharacter, then use eval to reverse 238 | # that process (while maintaining the separation between arguments), and wrap 239 | # the whole thing up as a single "set" statement. 240 | # 241 | # This will of course break if any of these variables contains a newline or 242 | # an unmatched quote. 243 | # 244 | 245 | eval "set -- $( 246 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 247 | xargs -n1 | 248 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 249 | tr '\n' ' ' 250 | )" '"$@"' 251 | 252 | exec "$JAVACMD" "$@" 253 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 74 | 75 | 76 | @rem Execute Gradle 77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 78 | 79 | :end 80 | @rem End local scope for the variables with windows NT shell 81 | if %ERRORLEVEL% equ 0 goto mainEnd 82 | 83 | :fail 84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 85 | rem the _cmd.exe /c_ return code! 86 | set EXIT_CODE=%ERRORLEVEL% 87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 89 | exit /b %EXIT_CODE% 90 | 91 | :mainEnd 92 | if "%OS%"=="Windows_NT" endlocal 93 | 94 | :omega 95 | -------------------------------------------------------------------------------- /libwebp-jni/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required( VERSION 2.8.12 ) 2 | set(CMAKE_OSX_DEPLOYMENT_TARGET "10.5" CACHE STRING "Minimum OS X deployment version") 3 | project ( webp-imageio ) 4 | 5 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 6 | 7 | add_subdirectory( "libwebp" ) 8 | add_subdirectory( "src/main/c" ) 9 | -------------------------------------------------------------------------------- /libwebp-jni/build.yml: -------------------------------------------------------------------------------- 1 | # This is the path where the so/dylib/dll generated by the CMake build script is located 2 | # TODO make this more configurable 3 | native_build_path: build/src/main/c -------------------------------------------------------------------------------- /libwebp-jni/compile-all.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -ex -o pipefail 3 | 4 | # Ensure clean build environments 5 | rm -rf build 6 | 7 | df -H 8 | ./dockcross/dockcross-linux-armv5 bash -c './compile.sh Linux arm' 9 | ./dockcross/dockcross-linux-armv6-lts bash -c './compile.sh Linux armv6' 10 | ./dockcross/dockcross-linux-armv7-lts bash -c './compile.sh Linux armv7' 11 | ./dockcross/dockcross-linux-arm64-lts bash -c './compile.sh Linux aarch64' 12 | ./dockcross/dockcross-manylinux-x86 bash -c './compile.sh Linux x86' 13 | ./dockcross/dockcross-manylinux-x64 bash -c './compile.sh Linux x86_64' 14 | ./dockcross/dockcross-linux-ppc64le bash -c './compile.sh Linux ppc64' 15 | 16 | df -H 17 | ./dockcross/dockcross-windows-static-x86 bash -c './compile.sh Windows x86' 18 | ./dockcross/dockcross-windows-static-x64 bash -c './compile.sh Windows x86_64' 19 | 20 | df -H 21 | docker run --rm -v $(pwd):/workdir -e CROSS_TRIPLE=x86_64-apple-darwin gotson/crossbuild ./compile.sh Mac x86_64 /workdir/multiarch-darwin.cmake 22 | docker run --rm -v $(pwd):/workdir -e CROSS_TRIPLE=aarch64-apple-darwin gotson/crossbuild ./compile.sh Mac aarch64 /workdir/multiarch-darwin.cmake 23 | 24 | df -H 25 | 26 | # Ensure clean target 27 | rm -r ../webp-imageio/src/main/resources/native 28 | cp -r build/native ../webp-imageio/src/main/resources/ 29 | -------------------------------------------------------------------------------- /libwebp-jni/compile.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo Building for OS: $1, Arch: $2, Toolchain: $3 3 | mkdir -p build/$1/$2 4 | cd build/$1/$2 5 | 6 | if [ -z "$3" ]; then 7 | cmake ../../.. 8 | else 9 | cmake ../../.. -DCMAKE_TOOLCHAIN_FILE=$3 10 | fi 11 | 12 | cmake --build . --config Release 13 | 14 | cd ../../.. 15 | 16 | LIB="libwebp-imageio.so" 17 | if [ "$1" == "Windows" ]; then 18 | LIB="webp-imageio.dll" 19 | elif [ "$1" == "Mac" ]; then 20 | LIB="libwebp-imageio.dylib" 21 | fi 22 | 23 | mkdir -p build/native/$1/$2/ 24 | cp build/$1/$2/src/main/c/${LIB} build/native/$1/$2/ 25 | -------------------------------------------------------------------------------- /libwebp-jni/dockcross/dockcross-linux-arm64-lts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DEFAULT_DOCKCROSS_IMAGE=dockcross/linux-arm64-lts:latest 4 | 5 | #------------------------------------------------------------------------------ 6 | # Helpers 7 | # 8 | err() { 9 | echo -e >&2 "ERROR: $*\n" 10 | } 11 | 12 | die() { 13 | err "$*" 14 | exit 1 15 | } 16 | 17 | has() { 18 | # eg. has command update 19 | local kind=$1 20 | local name=$2 21 | 22 | type -t $kind:$name | grep -q function 23 | } 24 | 25 | # If OCI_EXE is not already set, search for a container executor (OCI stands for "Open Container Initiative") 26 | if [ -z "$OCI_EXE" ]; then 27 | if which podman >/dev/null 2>/dev/null; then 28 | OCI_EXE=podman 29 | elif which docker >/dev/null 2>/dev/null; then 30 | OCI_EXE=docker 31 | else 32 | die "Cannot find a container executor. Search for docker and podman." 33 | fi 34 | fi 35 | 36 | #------------------------------------------------------------------------------ 37 | # Command handlers 38 | # 39 | command:update-image() { 40 | $OCI_EXE pull $FINAL_IMAGE 41 | } 42 | 43 | help:update-image() { 44 | echo "Pull the latest $FINAL_IMAGE ." 45 | } 46 | 47 | command:update-script() { 48 | if cmp -s <( $OCI_EXE run --rm $FINAL_IMAGE ) $0; then 49 | echo "$0 is up to date" 50 | else 51 | echo -n "Updating $0 ... " 52 | $OCI_EXE run --rm $FINAL_IMAGE > $0 && echo ok 53 | fi 54 | } 55 | 56 | help:update-script() { 57 | echo "Update $0 from $FINAL_IMAGE ." 58 | } 59 | 60 | command:update() { 61 | command:update-image 62 | command:update-script 63 | } 64 | 65 | help:update() { 66 | echo "Pull the latest $FINAL_IMAGE, and then update $0 from that." 67 | } 68 | 69 | command:help() { 70 | if [[ $# != 0 ]]; then 71 | if ! has command $1; then 72 | err \"$1\" is not an dockcross command 73 | command:help 74 | elif ! has help $1; then 75 | err No help found for \"$1\" 76 | else 77 | help:$1 78 | fi 79 | else 80 | cat >&2 < 99 | ENDHELP 100 | exit 1 101 | fi 102 | } 103 | 104 | #------------------------------------------------------------------------------ 105 | # Option processing 106 | # 107 | special_update_command='' 108 | while [[ $# != 0 ]]; do 109 | case $1 in 110 | 111 | --) 112 | shift 113 | break 114 | ;; 115 | 116 | --args|-a) 117 | ARG_ARGS="$2" 118 | shift 2 119 | ;; 120 | 121 | --config|-c) 122 | ARG_CONFIG="$2" 123 | shift 2 124 | ;; 125 | 126 | --image|-i) 127 | ARG_IMAGE="$2" 128 | shift 2 129 | ;; 130 | update|update-image|update-script) 131 | special_update_command=$1 132 | break 133 | ;; 134 | -*) 135 | err Unknown option \"$1\" 136 | command:help 137 | exit 138 | ;; 139 | 140 | *) 141 | break 142 | ;; 143 | 144 | esac 145 | done 146 | 147 | # The precedence for options is: 148 | # 1. command-line arguments 149 | # 2. environment variables 150 | # 3. defaults 151 | 152 | # Source the config file if it exists 153 | DEFAULT_DOCKCROSS_CONFIG=~/.dockcross 154 | FINAL_CONFIG=${ARG_CONFIG-${DOCKCROSS_CONFIG-$DEFAULT_DOCKCROSS_CONFIG}} 155 | 156 | [[ -f "$FINAL_CONFIG" ]] && source "$FINAL_CONFIG" 157 | 158 | # Set the docker image 159 | FINAL_IMAGE=${ARG_IMAGE-${DOCKCROSS_IMAGE-$DEFAULT_DOCKCROSS_IMAGE}} 160 | 161 | # Handle special update command 162 | if [ "$special_update_command" != "" ]; then 163 | case $special_update_command in 164 | 165 | update) 166 | command:update 167 | exit $? 168 | ;; 169 | 170 | update-image) 171 | command:update-image 172 | exit $? 173 | ;; 174 | 175 | update-script) 176 | command:update-script 177 | exit $? 178 | ;; 179 | 180 | esac 181 | fi 182 | 183 | # Set the docker run extra args (if any) 184 | FINAL_ARGS=${ARG_ARGS-${DOCKCROSS_ARGS}} 185 | 186 | # Bash on Ubuntu on Windows 187 | UBUNTU_ON_WINDOWS=$([ -e /proc/version ] && grep -l Microsoft /proc/version || echo "") 188 | # MSYS, Git Bash, etc. 189 | MSYS=$([ -e /proc/version ] && grep -l MINGW /proc/version || echo "") 190 | # CYGWIN 191 | CYGWIN=$([ -e /proc/version ] && grep -l CYGWIN /proc/version || echo "") 192 | 193 | if [ -z "$UBUNTU_ON_WINDOWS" -a -z "$MSYS" -a "$OCI_EXE" != "podman" ]; then 194 | USER_IDS=(-e BUILDER_UID="$( id -u )" -e BUILDER_GID="$( id -g )" -e BUILDER_USER="$( id -un )" -e BUILDER_GROUP="$( id -gn )") 195 | fi 196 | 197 | # Change the PWD when working in Docker on Windows 198 | if [ -n "$UBUNTU_ON_WINDOWS" ]; then 199 | WSL_ROOT="/mnt/" 200 | CFG_FILE=/etc/wsl.conf 201 | if [ -f "$CFG_FILE" ]; then 202 | CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g') 203 | eval "$CFG_CONTENT" 204 | if [ -n "$root" ]; then 205 | WSL_ROOT=$root 206 | fi 207 | fi 208 | HOST_PWD=`pwd -P` 209 | HOST_PWD=${HOST_PWD/$WSL_ROOT//} 210 | elif [ -n "$MSYS" ]; then 211 | HOST_PWD=$PWD 212 | HOST_PWD=${HOST_PWD/\//} 213 | HOST_PWD=${HOST_PWD/\//:\/} 214 | elif [ -n "$CYGWIN" ]; then 215 | for f in pwd readlink cygpath ; do 216 | test -n "$(type "${f}" )" || { echo >&2 "Missing functionality (${f}) (in cygwin)." ; exit 1 ; } ; 217 | done ; 218 | HOST_PWD="$( cygpath -w "$( readlink -f "$( pwd ;)" ; )" ; )" ; 219 | else 220 | HOST_PWD=$PWD 221 | [ -L $HOST_PWD ] && HOST_PWD=$(readlink $HOST_PWD) 222 | fi 223 | 224 | # Mount Additional Volumes 225 | if [ -z "$SSH_DIR" ]; then 226 | SSH_DIR="$HOME/.ssh" 227 | fi 228 | 229 | HOST_VOLUMES= 230 | if [ -e "$SSH_DIR" -a -z "$MSYS" ]; then 231 | if test -n "${CYGWIN}" ; then 232 | HOST_VOLUMES+="-v $(cygpath -w ${SSH_DIR} ; ):/home/$(id -un)/.ssh" ; 233 | else 234 | HOST_VOLUMES+="-v $SSH_DIR:/home/$(id -un)/.ssh" ; 235 | fi ; 236 | fi 237 | 238 | #------------------------------------------------------------------------------ 239 | # Now, finally, run the command in a container 240 | # 241 | TTY_ARGS= 242 | tty -s && [ -z "$MSYS" ] && TTY_ARGS=-ti 243 | CONTAINER_NAME=dockcross_$RANDOM 244 | $OCI_EXE run $TTY_ARGS --name $CONTAINER_NAME \ 245 | -v "$HOST_PWD":/work \ 246 | $HOST_VOLUMES \ 247 | "${USER_IDS[@]}" \ 248 | $FINAL_ARGS \ 249 | $FINAL_IMAGE "$@" 250 | run_exit_code=$? 251 | 252 | # Attempt to delete container 253 | rm_output=$($OCI_EXE rm -f $CONTAINER_NAME 2>&1) 254 | rm_exit_code=$? 255 | if [[ $rm_exit_code != 0 ]]; then 256 | if [[ "$CIRCLECI" == "true" ]] && [[ $rm_output == *"Driver btrfs failed to remove"* ]]; then 257 | : # Ignore error because of https://circleci.com/docs/docker-btrfs-error/ 258 | else 259 | echo "$rm_output" 260 | exit $rm_exit_code 261 | fi 262 | fi 263 | 264 | exit $run_exit_code 265 | 266 | ################################################################################ 267 | # 268 | # This image is not intended to be run manually. 269 | # 270 | # To create a dockcross helper script for the 271 | # dockcross/linux-arm64-lts:20230601-c2f5366 image, run: 272 | # 273 | # docker run --rm dockcross/linux-arm64-lts:20230601-c2f5366 > dockcross-linux-arm64-lts-20230601-c2f5366 274 | # chmod +x dockcross-linux-arm64-lts-20230601-c2f5366 275 | # 276 | # You may then wish to move the dockcross script to your PATH. 277 | # 278 | ################################################################################ 279 | -------------------------------------------------------------------------------- /libwebp-jni/dockcross/dockcross-linux-armv5: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DEFAULT_DOCKCROSS_IMAGE=dockcross/linux-armv5:latest 4 | 5 | #------------------------------------------------------------------------------ 6 | # Helpers 7 | # 8 | err() { 9 | echo -e >&2 "ERROR: $*\n" 10 | } 11 | 12 | die() { 13 | err "$*" 14 | exit 1 15 | } 16 | 17 | has() { 18 | # eg. has command update 19 | local kind=$1 20 | local name=$2 21 | 22 | type -t $kind:$name | grep -q function 23 | } 24 | 25 | # If OCI_EXE is not already set, search for a container executor (OCI stands for "Open Container Initiative") 26 | if [ -z "$OCI_EXE" ]; then 27 | if which podman >/dev/null 2>/dev/null; then 28 | OCI_EXE=podman 29 | elif which docker >/dev/null 2>/dev/null; then 30 | OCI_EXE=docker 31 | else 32 | die "Cannot find a container executor. Search for docker and podman." 33 | fi 34 | fi 35 | 36 | #------------------------------------------------------------------------------ 37 | # Command handlers 38 | # 39 | command:update-image() { 40 | $OCI_EXE pull $FINAL_IMAGE 41 | } 42 | 43 | help:update-image() { 44 | echo "Pull the latest $FINAL_IMAGE ." 45 | } 46 | 47 | command:update-script() { 48 | if cmp -s <( $OCI_EXE run --rm $FINAL_IMAGE ) $0; then 49 | echo "$0 is up to date" 50 | else 51 | echo -n "Updating $0 ... " 52 | $OCI_EXE run --rm $FINAL_IMAGE > $0 && echo ok 53 | fi 54 | } 55 | 56 | help:update-script() { 57 | echo "Update $0 from $FINAL_IMAGE ." 58 | } 59 | 60 | command:update() { 61 | command:update-image 62 | command:update-script 63 | } 64 | 65 | help:update() { 66 | echo "Pull the latest $FINAL_IMAGE, and then update $0 from that." 67 | } 68 | 69 | command:help() { 70 | if [[ $# != 0 ]]; then 71 | if ! has command $1; then 72 | err \"$1\" is not an dockcross command 73 | command:help 74 | elif ! has help $1; then 75 | err No help found for \"$1\" 76 | else 77 | help:$1 78 | fi 79 | else 80 | cat >&2 < 99 | ENDHELP 100 | exit 1 101 | fi 102 | } 103 | 104 | #------------------------------------------------------------------------------ 105 | # Option processing 106 | # 107 | special_update_command='' 108 | while [[ $# != 0 ]]; do 109 | case $1 in 110 | 111 | --) 112 | shift 113 | break 114 | ;; 115 | 116 | --args|-a) 117 | ARG_ARGS="$2" 118 | shift 2 119 | ;; 120 | 121 | --config|-c) 122 | ARG_CONFIG="$2" 123 | shift 2 124 | ;; 125 | 126 | --image|-i) 127 | ARG_IMAGE="$2" 128 | shift 2 129 | ;; 130 | update|update-image|update-script) 131 | special_update_command=$1 132 | break 133 | ;; 134 | -*) 135 | err Unknown option \"$1\" 136 | command:help 137 | exit 138 | ;; 139 | 140 | *) 141 | break 142 | ;; 143 | 144 | esac 145 | done 146 | 147 | # The precedence for options is: 148 | # 1. command-line arguments 149 | # 2. environment variables 150 | # 3. defaults 151 | 152 | # Source the config file if it exists 153 | DEFAULT_DOCKCROSS_CONFIG=~/.dockcross 154 | FINAL_CONFIG=${ARG_CONFIG-${DOCKCROSS_CONFIG-$DEFAULT_DOCKCROSS_CONFIG}} 155 | 156 | [[ -f "$FINAL_CONFIG" ]] && source "$FINAL_CONFIG" 157 | 158 | # Set the docker image 159 | FINAL_IMAGE=${ARG_IMAGE-${DOCKCROSS_IMAGE-$DEFAULT_DOCKCROSS_IMAGE}} 160 | 161 | # Handle special update command 162 | if [ "$special_update_command" != "" ]; then 163 | case $special_update_command in 164 | 165 | update) 166 | command:update 167 | exit $? 168 | ;; 169 | 170 | update-image) 171 | command:update-image 172 | exit $? 173 | ;; 174 | 175 | update-script) 176 | command:update-script 177 | exit $? 178 | ;; 179 | 180 | esac 181 | fi 182 | 183 | # Set the docker run extra args (if any) 184 | FINAL_ARGS=${ARG_ARGS-${DOCKCROSS_ARGS}} 185 | 186 | # Bash on Ubuntu on Windows 187 | UBUNTU_ON_WINDOWS=$([ -e /proc/version ] && grep -l Microsoft /proc/version || echo "") 188 | # MSYS, Git Bash, etc. 189 | MSYS=$([ -e /proc/version ] && grep -l MINGW /proc/version || echo "") 190 | # CYGWIN 191 | CYGWIN=$([ -e /proc/version ] && grep -l CYGWIN /proc/version || echo "") 192 | 193 | if [ -z "$UBUNTU_ON_WINDOWS" -a -z "$MSYS" -a "$OCI_EXE" != "podman" ]; then 194 | USER_IDS=(-e BUILDER_UID="$( id -u )" -e BUILDER_GID="$( id -g )" -e BUILDER_USER="$( id -un )" -e BUILDER_GROUP="$( id -gn )") 195 | fi 196 | 197 | # Change the PWD when working in Docker on Windows 198 | if [ -n "$UBUNTU_ON_WINDOWS" ]; then 199 | WSL_ROOT="/mnt/" 200 | CFG_FILE=/etc/wsl.conf 201 | if [ -f "$CFG_FILE" ]; then 202 | CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g') 203 | eval "$CFG_CONTENT" 204 | if [ -n "$root" ]; then 205 | WSL_ROOT=$root 206 | fi 207 | fi 208 | HOST_PWD=`pwd -P` 209 | HOST_PWD=${HOST_PWD/$WSL_ROOT//} 210 | elif [ -n "$MSYS" ]; then 211 | HOST_PWD=$PWD 212 | HOST_PWD=${HOST_PWD/\//} 213 | HOST_PWD=${HOST_PWD/\//:\/} 214 | elif [ -n "$CYGWIN" ]; then 215 | for f in pwd readlink cygpath ; do 216 | test -n "$(type "${f}" )" || { echo >&2 "Missing functionality (${f}) (in cygwin)." ; exit 1 ; } ; 217 | done ; 218 | HOST_PWD="$( cygpath -w "$( readlink -f "$( pwd ;)" ; )" ; )" ; 219 | else 220 | HOST_PWD=$PWD 221 | [ -L $HOST_PWD ] && HOST_PWD=$(readlink $HOST_PWD) 222 | fi 223 | 224 | # Mount Additional Volumes 225 | if [ -z "$SSH_DIR" ]; then 226 | SSH_DIR="$HOME/.ssh" 227 | fi 228 | 229 | HOST_VOLUMES= 230 | if [ -e "$SSH_DIR" -a -z "$MSYS" ]; then 231 | if test -n "${CYGWIN}" ; then 232 | HOST_VOLUMES+="-v $(cygpath -w ${SSH_DIR} ; ):/home/$(id -un)/.ssh" ; 233 | else 234 | HOST_VOLUMES+="-v $SSH_DIR:/home/$(id -un)/.ssh" ; 235 | fi ; 236 | fi 237 | 238 | #------------------------------------------------------------------------------ 239 | # Now, finally, run the command in a container 240 | # 241 | TTY_ARGS= 242 | tty -s && [ -z "$MSYS" ] && TTY_ARGS=-ti 243 | CONTAINER_NAME=dockcross_$RANDOM 244 | $OCI_EXE run $TTY_ARGS --name $CONTAINER_NAME \ 245 | -v "$HOST_PWD":/work \ 246 | $HOST_VOLUMES \ 247 | "${USER_IDS[@]}" \ 248 | $FINAL_ARGS \ 249 | $FINAL_IMAGE "$@" 250 | run_exit_code=$? 251 | 252 | # Attempt to delete container 253 | rm_output=$($OCI_EXE rm -f $CONTAINER_NAME 2>&1) 254 | rm_exit_code=$? 255 | if [[ $rm_exit_code != 0 ]]; then 256 | if [[ "$CIRCLECI" == "true" ]] && [[ $rm_output == *"Driver btrfs failed to remove"* ]]; then 257 | : # Ignore error because of https://circleci.com/docs/docker-btrfs-error/ 258 | else 259 | echo "$rm_output" 260 | exit $rm_exit_code 261 | fi 262 | fi 263 | 264 | exit $run_exit_code 265 | 266 | ################################################################################ 267 | # 268 | # This image is not intended to be run manually. 269 | # 270 | # To create a dockcross helper script for the 271 | # dockcross/linux-armv5:20230601-c2f5366 image, run: 272 | # 273 | # docker run --rm dockcross/linux-armv5:20230601-c2f5366 > dockcross-linux-armv5-20230601-c2f5366 274 | # chmod +x dockcross-linux-armv5-20230601-c2f5366 275 | # 276 | # You may then wish to move the dockcross script to your PATH. 277 | # 278 | ################################################################################ 279 | -------------------------------------------------------------------------------- /libwebp-jni/dockcross/dockcross-linux-armv6-lts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DEFAULT_DOCKCROSS_IMAGE=dockcross/linux-armv6-lts:latest 4 | 5 | #------------------------------------------------------------------------------ 6 | # Helpers 7 | # 8 | err() { 9 | echo -e >&2 "ERROR: $*\n" 10 | } 11 | 12 | die() { 13 | err "$*" 14 | exit 1 15 | } 16 | 17 | has() { 18 | # eg. has command update 19 | local kind=$1 20 | local name=$2 21 | 22 | type -t $kind:$name | grep -q function 23 | } 24 | 25 | # If OCI_EXE is not already set, search for a container executor (OCI stands for "Open Container Initiative") 26 | if [ -z "$OCI_EXE" ]; then 27 | if which podman >/dev/null 2>/dev/null; then 28 | OCI_EXE=podman 29 | elif which docker >/dev/null 2>/dev/null; then 30 | OCI_EXE=docker 31 | else 32 | die "Cannot find a container executor. Search for docker and podman." 33 | fi 34 | fi 35 | 36 | #------------------------------------------------------------------------------ 37 | # Command handlers 38 | # 39 | command:update-image() { 40 | $OCI_EXE pull $FINAL_IMAGE 41 | } 42 | 43 | help:update-image() { 44 | echo "Pull the latest $FINAL_IMAGE ." 45 | } 46 | 47 | command:update-script() { 48 | if cmp -s <( $OCI_EXE run --rm $FINAL_IMAGE ) $0; then 49 | echo "$0 is up to date" 50 | else 51 | echo -n "Updating $0 ... " 52 | $OCI_EXE run --rm $FINAL_IMAGE > $0 && echo ok 53 | fi 54 | } 55 | 56 | help:update-script() { 57 | echo "Update $0 from $FINAL_IMAGE ." 58 | } 59 | 60 | command:update() { 61 | command:update-image 62 | command:update-script 63 | } 64 | 65 | help:update() { 66 | echo "Pull the latest $FINAL_IMAGE, and then update $0 from that." 67 | } 68 | 69 | command:help() { 70 | if [[ $# != 0 ]]; then 71 | if ! has command $1; then 72 | err \"$1\" is not an dockcross command 73 | command:help 74 | elif ! has help $1; then 75 | err No help found for \"$1\" 76 | else 77 | help:$1 78 | fi 79 | else 80 | cat >&2 < 99 | ENDHELP 100 | exit 1 101 | fi 102 | } 103 | 104 | #------------------------------------------------------------------------------ 105 | # Option processing 106 | # 107 | special_update_command='' 108 | while [[ $# != 0 ]]; do 109 | case $1 in 110 | 111 | --) 112 | shift 113 | break 114 | ;; 115 | 116 | --args|-a) 117 | ARG_ARGS="$2" 118 | shift 2 119 | ;; 120 | 121 | --config|-c) 122 | ARG_CONFIG="$2" 123 | shift 2 124 | ;; 125 | 126 | --image|-i) 127 | ARG_IMAGE="$2" 128 | shift 2 129 | ;; 130 | update|update-image|update-script) 131 | special_update_command=$1 132 | break 133 | ;; 134 | -*) 135 | err Unknown option \"$1\" 136 | command:help 137 | exit 138 | ;; 139 | 140 | *) 141 | break 142 | ;; 143 | 144 | esac 145 | done 146 | 147 | # The precedence for options is: 148 | # 1. command-line arguments 149 | # 2. environment variables 150 | # 3. defaults 151 | 152 | # Source the config file if it exists 153 | DEFAULT_DOCKCROSS_CONFIG=~/.dockcross 154 | FINAL_CONFIG=${ARG_CONFIG-${DOCKCROSS_CONFIG-$DEFAULT_DOCKCROSS_CONFIG}} 155 | 156 | [[ -f "$FINAL_CONFIG" ]] && source "$FINAL_CONFIG" 157 | 158 | # Set the docker image 159 | FINAL_IMAGE=${ARG_IMAGE-${DOCKCROSS_IMAGE-$DEFAULT_DOCKCROSS_IMAGE}} 160 | 161 | # Handle special update command 162 | if [ "$special_update_command" != "" ]; then 163 | case $special_update_command in 164 | 165 | update) 166 | command:update 167 | exit $? 168 | ;; 169 | 170 | update-image) 171 | command:update-image 172 | exit $? 173 | ;; 174 | 175 | update-script) 176 | command:update-script 177 | exit $? 178 | ;; 179 | 180 | esac 181 | fi 182 | 183 | # Set the docker run extra args (if any) 184 | FINAL_ARGS=${ARG_ARGS-${DOCKCROSS_ARGS}} 185 | 186 | # Bash on Ubuntu on Windows 187 | UBUNTU_ON_WINDOWS=$([ -e /proc/version ] && grep -l Microsoft /proc/version || echo "") 188 | # MSYS, Git Bash, etc. 189 | MSYS=$([ -e /proc/version ] && grep -l MINGW /proc/version || echo "") 190 | # CYGWIN 191 | CYGWIN=$([ -e /proc/version ] && grep -l CYGWIN /proc/version || echo "") 192 | 193 | if [ -z "$UBUNTU_ON_WINDOWS" -a -z "$MSYS" -a "$OCI_EXE" != "podman" ]; then 194 | USER_IDS=(-e BUILDER_UID="$( id -u )" -e BUILDER_GID="$( id -g )" -e BUILDER_USER="$( id -un )" -e BUILDER_GROUP="$( id -gn )") 195 | fi 196 | 197 | # Change the PWD when working in Docker on Windows 198 | if [ -n "$UBUNTU_ON_WINDOWS" ]; then 199 | WSL_ROOT="/mnt/" 200 | CFG_FILE=/etc/wsl.conf 201 | if [ -f "$CFG_FILE" ]; then 202 | CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g') 203 | eval "$CFG_CONTENT" 204 | if [ -n "$root" ]; then 205 | WSL_ROOT=$root 206 | fi 207 | fi 208 | HOST_PWD=`pwd -P` 209 | HOST_PWD=${HOST_PWD/$WSL_ROOT//} 210 | elif [ -n "$MSYS" ]; then 211 | HOST_PWD=$PWD 212 | HOST_PWD=${HOST_PWD/\//} 213 | HOST_PWD=${HOST_PWD/\//:\/} 214 | elif [ -n "$CYGWIN" ]; then 215 | for f in pwd readlink cygpath ; do 216 | test -n "$(type "${f}" )" || { echo >&2 "Missing functionality (${f}) (in cygwin)." ; exit 1 ; } ; 217 | done ; 218 | HOST_PWD="$( cygpath -w "$( readlink -f "$( pwd ;)" ; )" ; )" ; 219 | else 220 | HOST_PWD=$PWD 221 | [ -L $HOST_PWD ] && HOST_PWD=$(readlink $HOST_PWD) 222 | fi 223 | 224 | # Mount Additional Volumes 225 | if [ -z "$SSH_DIR" ]; then 226 | SSH_DIR="$HOME/.ssh" 227 | fi 228 | 229 | HOST_VOLUMES= 230 | if [ -e "$SSH_DIR" -a -z "$MSYS" ]; then 231 | if test -n "${CYGWIN}" ; then 232 | HOST_VOLUMES+="-v $(cygpath -w ${SSH_DIR} ; ):/home/$(id -un)/.ssh" ; 233 | else 234 | HOST_VOLUMES+="-v $SSH_DIR:/home/$(id -un)/.ssh" ; 235 | fi ; 236 | fi 237 | 238 | #------------------------------------------------------------------------------ 239 | # Now, finally, run the command in a container 240 | # 241 | TTY_ARGS= 242 | tty -s && [ -z "$MSYS" ] && TTY_ARGS=-ti 243 | CONTAINER_NAME=dockcross_$RANDOM 244 | $OCI_EXE run $TTY_ARGS --name $CONTAINER_NAME \ 245 | -v "$HOST_PWD":/work \ 246 | $HOST_VOLUMES \ 247 | "${USER_IDS[@]}" \ 248 | $FINAL_ARGS \ 249 | $FINAL_IMAGE "$@" 250 | run_exit_code=$? 251 | 252 | # Attempt to delete container 253 | rm_output=$($OCI_EXE rm -f $CONTAINER_NAME 2>&1) 254 | rm_exit_code=$? 255 | if [[ $rm_exit_code != 0 ]]; then 256 | if [[ "$CIRCLECI" == "true" ]] && [[ $rm_output == *"Driver btrfs failed to remove"* ]]; then 257 | : # Ignore error because of https://circleci.com/docs/docker-btrfs-error/ 258 | else 259 | echo "$rm_output" 260 | exit $rm_exit_code 261 | fi 262 | fi 263 | 264 | exit $run_exit_code 265 | 266 | ################################################################################ 267 | # 268 | # This image is not intended to be run manually. 269 | # 270 | # To create a dockcross helper script for the 271 | # dockcross/linux-armv6-lts:20230601-c2f5366 image, run: 272 | # 273 | # docker run --rm dockcross/linux-armv6-lts:20230601-c2f5366 > dockcross-linux-armv6-lts-20230601-c2f5366 274 | # chmod +x dockcross-linux-armv6-lts-20230601-c2f5366 275 | # 276 | # You may then wish to move the dockcross script to your PATH. 277 | # 278 | ################################################################################ 279 | -------------------------------------------------------------------------------- /libwebp-jni/dockcross/dockcross-linux-armv7-lts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DEFAULT_DOCKCROSS_IMAGE=dockcross/linux-armv7-lts:latest 4 | 5 | #------------------------------------------------------------------------------ 6 | # Helpers 7 | # 8 | err() { 9 | echo -e >&2 "ERROR: $*\n" 10 | } 11 | 12 | die() { 13 | err "$*" 14 | exit 1 15 | } 16 | 17 | has() { 18 | # eg. has command update 19 | local kind=$1 20 | local name=$2 21 | 22 | type -t $kind:$name | grep -q function 23 | } 24 | 25 | # If OCI_EXE is not already set, search for a container executor (OCI stands for "Open Container Initiative") 26 | if [ -z "$OCI_EXE" ]; then 27 | if which podman >/dev/null 2>/dev/null; then 28 | OCI_EXE=podman 29 | elif which docker >/dev/null 2>/dev/null; then 30 | OCI_EXE=docker 31 | else 32 | die "Cannot find a container executor. Search for docker and podman." 33 | fi 34 | fi 35 | 36 | #------------------------------------------------------------------------------ 37 | # Command handlers 38 | # 39 | command:update-image() { 40 | $OCI_EXE pull $FINAL_IMAGE 41 | } 42 | 43 | help:update-image() { 44 | echo "Pull the latest $FINAL_IMAGE ." 45 | } 46 | 47 | command:update-script() { 48 | if cmp -s <( $OCI_EXE run --rm $FINAL_IMAGE ) $0; then 49 | echo "$0 is up to date" 50 | else 51 | echo -n "Updating $0 ... " 52 | $OCI_EXE run --rm $FINAL_IMAGE > $0 && echo ok 53 | fi 54 | } 55 | 56 | help:update-script() { 57 | echo "Update $0 from $FINAL_IMAGE ." 58 | } 59 | 60 | command:update() { 61 | command:update-image 62 | command:update-script 63 | } 64 | 65 | help:update() { 66 | echo "Pull the latest $FINAL_IMAGE, and then update $0 from that." 67 | } 68 | 69 | command:help() { 70 | if [[ $# != 0 ]]; then 71 | if ! has command $1; then 72 | err \"$1\" is not an dockcross command 73 | command:help 74 | elif ! has help $1; then 75 | err No help found for \"$1\" 76 | else 77 | help:$1 78 | fi 79 | else 80 | cat >&2 < 99 | ENDHELP 100 | exit 1 101 | fi 102 | } 103 | 104 | #------------------------------------------------------------------------------ 105 | # Option processing 106 | # 107 | special_update_command='' 108 | while [[ $# != 0 ]]; do 109 | case $1 in 110 | 111 | --) 112 | shift 113 | break 114 | ;; 115 | 116 | --args|-a) 117 | ARG_ARGS="$2" 118 | shift 2 119 | ;; 120 | 121 | --config|-c) 122 | ARG_CONFIG="$2" 123 | shift 2 124 | ;; 125 | 126 | --image|-i) 127 | ARG_IMAGE="$2" 128 | shift 2 129 | ;; 130 | update|update-image|update-script) 131 | special_update_command=$1 132 | break 133 | ;; 134 | -*) 135 | err Unknown option \"$1\" 136 | command:help 137 | exit 138 | ;; 139 | 140 | *) 141 | break 142 | ;; 143 | 144 | esac 145 | done 146 | 147 | # The precedence for options is: 148 | # 1. command-line arguments 149 | # 2. environment variables 150 | # 3. defaults 151 | 152 | # Source the config file if it exists 153 | DEFAULT_DOCKCROSS_CONFIG=~/.dockcross 154 | FINAL_CONFIG=${ARG_CONFIG-${DOCKCROSS_CONFIG-$DEFAULT_DOCKCROSS_CONFIG}} 155 | 156 | [[ -f "$FINAL_CONFIG" ]] && source "$FINAL_CONFIG" 157 | 158 | # Set the docker image 159 | FINAL_IMAGE=${ARG_IMAGE-${DOCKCROSS_IMAGE-$DEFAULT_DOCKCROSS_IMAGE}} 160 | 161 | # Handle special update command 162 | if [ "$special_update_command" != "" ]; then 163 | case $special_update_command in 164 | 165 | update) 166 | command:update 167 | exit $? 168 | ;; 169 | 170 | update-image) 171 | command:update-image 172 | exit $? 173 | ;; 174 | 175 | update-script) 176 | command:update-script 177 | exit $? 178 | ;; 179 | 180 | esac 181 | fi 182 | 183 | # Set the docker run extra args (if any) 184 | FINAL_ARGS=${ARG_ARGS-${DOCKCROSS_ARGS}} 185 | 186 | # Bash on Ubuntu on Windows 187 | UBUNTU_ON_WINDOWS=$([ -e /proc/version ] && grep -l Microsoft /proc/version || echo "") 188 | # MSYS, Git Bash, etc. 189 | MSYS=$([ -e /proc/version ] && grep -l MINGW /proc/version || echo "") 190 | # CYGWIN 191 | CYGWIN=$([ -e /proc/version ] && grep -l CYGWIN /proc/version || echo "") 192 | 193 | if [ -z "$UBUNTU_ON_WINDOWS" -a -z "$MSYS" -a "$OCI_EXE" != "podman" ]; then 194 | USER_IDS=(-e BUILDER_UID="$( id -u )" -e BUILDER_GID="$( id -g )" -e BUILDER_USER="$( id -un )" -e BUILDER_GROUP="$( id -gn )") 195 | fi 196 | 197 | # Change the PWD when working in Docker on Windows 198 | if [ -n "$UBUNTU_ON_WINDOWS" ]; then 199 | WSL_ROOT="/mnt/" 200 | CFG_FILE=/etc/wsl.conf 201 | if [ -f "$CFG_FILE" ]; then 202 | CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g') 203 | eval "$CFG_CONTENT" 204 | if [ -n "$root" ]; then 205 | WSL_ROOT=$root 206 | fi 207 | fi 208 | HOST_PWD=`pwd -P` 209 | HOST_PWD=${HOST_PWD/$WSL_ROOT//} 210 | elif [ -n "$MSYS" ]; then 211 | HOST_PWD=$PWD 212 | HOST_PWD=${HOST_PWD/\//} 213 | HOST_PWD=${HOST_PWD/\//:\/} 214 | elif [ -n "$CYGWIN" ]; then 215 | for f in pwd readlink cygpath ; do 216 | test -n "$(type "${f}" )" || { echo >&2 "Missing functionality (${f}) (in cygwin)." ; exit 1 ; } ; 217 | done ; 218 | HOST_PWD="$( cygpath -w "$( readlink -f "$( pwd ;)" ; )" ; )" ; 219 | else 220 | HOST_PWD=$PWD 221 | [ -L $HOST_PWD ] && HOST_PWD=$(readlink $HOST_PWD) 222 | fi 223 | 224 | # Mount Additional Volumes 225 | if [ -z "$SSH_DIR" ]; then 226 | SSH_DIR="$HOME/.ssh" 227 | fi 228 | 229 | HOST_VOLUMES= 230 | if [ -e "$SSH_DIR" -a -z "$MSYS" ]; then 231 | if test -n "${CYGWIN}" ; then 232 | HOST_VOLUMES+="-v $(cygpath -w ${SSH_DIR} ; ):/home/$(id -un)/.ssh" ; 233 | else 234 | HOST_VOLUMES+="-v $SSH_DIR:/home/$(id -un)/.ssh" ; 235 | fi ; 236 | fi 237 | 238 | #------------------------------------------------------------------------------ 239 | # Now, finally, run the command in a container 240 | # 241 | TTY_ARGS= 242 | tty -s && [ -z "$MSYS" ] && TTY_ARGS=-ti 243 | CONTAINER_NAME=dockcross_$RANDOM 244 | $OCI_EXE run $TTY_ARGS --name $CONTAINER_NAME \ 245 | -v "$HOST_PWD":/work \ 246 | $HOST_VOLUMES \ 247 | "${USER_IDS[@]}" \ 248 | $FINAL_ARGS \ 249 | $FINAL_IMAGE "$@" 250 | run_exit_code=$? 251 | 252 | # Attempt to delete container 253 | rm_output=$($OCI_EXE rm -f $CONTAINER_NAME 2>&1) 254 | rm_exit_code=$? 255 | if [[ $rm_exit_code != 0 ]]; then 256 | if [[ "$CIRCLECI" == "true" ]] && [[ $rm_output == *"Driver btrfs failed to remove"* ]]; then 257 | : # Ignore error because of https://circleci.com/docs/docker-btrfs-error/ 258 | else 259 | echo "$rm_output" 260 | exit $rm_exit_code 261 | fi 262 | fi 263 | 264 | exit $run_exit_code 265 | 266 | ################################################################################ 267 | # 268 | # This image is not intended to be run manually. 269 | # 270 | # To create a dockcross helper script for the 271 | # dockcross/linux-armv7-lts:20230601-c2f5366 image, run: 272 | # 273 | # docker run --rm dockcross/linux-armv7-lts:20230601-c2f5366 > dockcross-linux-armv7-lts-20230601-c2f5366 274 | # chmod +x dockcross-linux-armv7-lts-20230601-c2f5366 275 | # 276 | # You may then wish to move the dockcross script to your PATH. 277 | # 278 | ################################################################################ 279 | -------------------------------------------------------------------------------- /libwebp-jni/dockcross/dockcross-linux-ppc64le: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DEFAULT_DOCKCROSS_IMAGE=dockcross/linux-ppc64le:latest 4 | 5 | #------------------------------------------------------------------------------ 6 | # Helpers 7 | # 8 | err() { 9 | echo -e >&2 "ERROR: $*\n" 10 | } 11 | 12 | die() { 13 | err "$*" 14 | exit 1 15 | } 16 | 17 | has() { 18 | # eg. has command update 19 | local kind=$1 20 | local name=$2 21 | 22 | type -t $kind:$name | grep -q function 23 | } 24 | 25 | # If OCI_EXE is not already set, search for a container executor (OCI stands for "Open Container Initiative") 26 | if [ -z "$OCI_EXE" ]; then 27 | if which podman >/dev/null 2>/dev/null; then 28 | OCI_EXE=podman 29 | elif which docker >/dev/null 2>/dev/null; then 30 | OCI_EXE=docker 31 | else 32 | die "Cannot find a container executor. Search for docker and podman." 33 | fi 34 | fi 35 | 36 | #------------------------------------------------------------------------------ 37 | # Command handlers 38 | # 39 | command:update-image() { 40 | $OCI_EXE pull $FINAL_IMAGE 41 | } 42 | 43 | help:update-image() { 44 | echo "Pull the latest $FINAL_IMAGE ." 45 | } 46 | 47 | command:update-script() { 48 | if cmp -s <( $OCI_EXE run --rm $FINAL_IMAGE ) $0; then 49 | echo "$0 is up to date" 50 | else 51 | echo -n "Updating $0 ... " 52 | $OCI_EXE run --rm $FINAL_IMAGE > $0 && echo ok 53 | fi 54 | } 55 | 56 | help:update-script() { 57 | echo "Update $0 from $FINAL_IMAGE ." 58 | } 59 | 60 | command:update() { 61 | command:update-image 62 | command:update-script 63 | } 64 | 65 | help:update() { 66 | echo "Pull the latest $FINAL_IMAGE, and then update $0 from that." 67 | } 68 | 69 | command:help() { 70 | if [[ $# != 0 ]]; then 71 | if ! has command $1; then 72 | err \"$1\" is not an dockcross command 73 | command:help 74 | elif ! has help $1; then 75 | err No help found for \"$1\" 76 | else 77 | help:$1 78 | fi 79 | else 80 | cat >&2 < 99 | ENDHELP 100 | exit 1 101 | fi 102 | } 103 | 104 | #------------------------------------------------------------------------------ 105 | # Option processing 106 | # 107 | special_update_command='' 108 | while [[ $# != 0 ]]; do 109 | case $1 in 110 | 111 | --) 112 | shift 113 | break 114 | ;; 115 | 116 | --args|-a) 117 | ARG_ARGS="$2" 118 | shift 2 119 | ;; 120 | 121 | --config|-c) 122 | ARG_CONFIG="$2" 123 | shift 2 124 | ;; 125 | 126 | --image|-i) 127 | ARG_IMAGE="$2" 128 | shift 2 129 | ;; 130 | update|update-image|update-script) 131 | special_update_command=$1 132 | break 133 | ;; 134 | -*) 135 | err Unknown option \"$1\" 136 | command:help 137 | exit 138 | ;; 139 | 140 | *) 141 | break 142 | ;; 143 | 144 | esac 145 | done 146 | 147 | # The precedence for options is: 148 | # 1. command-line arguments 149 | # 2. environment variables 150 | # 3. defaults 151 | 152 | # Source the config file if it exists 153 | DEFAULT_DOCKCROSS_CONFIG=~/.dockcross 154 | FINAL_CONFIG=${ARG_CONFIG-${DOCKCROSS_CONFIG-$DEFAULT_DOCKCROSS_CONFIG}} 155 | 156 | [[ -f "$FINAL_CONFIG" ]] && source "$FINAL_CONFIG" 157 | 158 | # Set the docker image 159 | FINAL_IMAGE=${ARG_IMAGE-${DOCKCROSS_IMAGE-$DEFAULT_DOCKCROSS_IMAGE}} 160 | 161 | # Handle special update command 162 | if [ "$special_update_command" != "" ]; then 163 | case $special_update_command in 164 | 165 | update) 166 | command:update 167 | exit $? 168 | ;; 169 | 170 | update-image) 171 | command:update-image 172 | exit $? 173 | ;; 174 | 175 | update-script) 176 | command:update-script 177 | exit $? 178 | ;; 179 | 180 | esac 181 | fi 182 | 183 | # Set the docker run extra args (if any) 184 | FINAL_ARGS=${ARG_ARGS-${DOCKCROSS_ARGS}} 185 | 186 | # Bash on Ubuntu on Windows 187 | UBUNTU_ON_WINDOWS=$([ -e /proc/version ] && grep -l Microsoft /proc/version || echo "") 188 | # MSYS, Git Bash, etc. 189 | MSYS=$([ -e /proc/version ] && grep -l MINGW /proc/version || echo "") 190 | # CYGWIN 191 | CYGWIN=$([ -e /proc/version ] && grep -l CYGWIN /proc/version || echo "") 192 | 193 | if [ -z "$UBUNTU_ON_WINDOWS" -a -z "$MSYS" -a "$OCI_EXE" != "podman" ]; then 194 | USER_IDS=(-e BUILDER_UID="$( id -u )" -e BUILDER_GID="$( id -g )" -e BUILDER_USER="$( id -un )" -e BUILDER_GROUP="$( id -gn )") 195 | fi 196 | 197 | # Change the PWD when working in Docker on Windows 198 | if [ -n "$UBUNTU_ON_WINDOWS" ]; then 199 | WSL_ROOT="/mnt/" 200 | CFG_FILE=/etc/wsl.conf 201 | if [ -f "$CFG_FILE" ]; then 202 | CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g') 203 | eval "$CFG_CONTENT" 204 | if [ -n "$root" ]; then 205 | WSL_ROOT=$root 206 | fi 207 | fi 208 | HOST_PWD=`pwd -P` 209 | HOST_PWD=${HOST_PWD/$WSL_ROOT//} 210 | elif [ -n "$MSYS" ]; then 211 | HOST_PWD=$PWD 212 | HOST_PWD=${HOST_PWD/\//} 213 | HOST_PWD=${HOST_PWD/\//:\/} 214 | elif [ -n "$CYGWIN" ]; then 215 | for f in pwd readlink cygpath ; do 216 | test -n "$(type "${f}" )" || { echo >&2 "Missing functionality (${f}) (in cygwin)." ; exit 1 ; } ; 217 | done ; 218 | HOST_PWD="$( cygpath -w "$( readlink -f "$( pwd ;)" ; )" ; )" ; 219 | else 220 | HOST_PWD=$PWD 221 | [ -L $HOST_PWD ] && HOST_PWD=$(readlink $HOST_PWD) 222 | fi 223 | 224 | # Mount Additional Volumes 225 | if [ -z "$SSH_DIR" ]; then 226 | SSH_DIR="$HOME/.ssh" 227 | fi 228 | 229 | HOST_VOLUMES= 230 | if [ -e "$SSH_DIR" -a -z "$MSYS" ]; then 231 | if test -n "${CYGWIN}" ; then 232 | HOST_VOLUMES+="-v $(cygpath -w ${SSH_DIR} ; ):/home/$(id -un)/.ssh" ; 233 | else 234 | HOST_VOLUMES+="-v $SSH_DIR:/home/$(id -un)/.ssh" ; 235 | fi ; 236 | fi 237 | 238 | #------------------------------------------------------------------------------ 239 | # Now, finally, run the command in a container 240 | # 241 | TTY_ARGS= 242 | tty -s && [ -z "$MSYS" ] && TTY_ARGS=-ti 243 | CONTAINER_NAME=dockcross_$RANDOM 244 | $OCI_EXE run $TTY_ARGS --name $CONTAINER_NAME \ 245 | -v "$HOST_PWD":/work \ 246 | $HOST_VOLUMES \ 247 | "${USER_IDS[@]}" \ 248 | $FINAL_ARGS \ 249 | $FINAL_IMAGE "$@" 250 | run_exit_code=$? 251 | 252 | # Attempt to delete container 253 | rm_output=$($OCI_EXE rm -f $CONTAINER_NAME 2>&1) 254 | rm_exit_code=$? 255 | if [[ $rm_exit_code != 0 ]]; then 256 | if [[ "$CIRCLECI" == "true" ]] && [[ $rm_output == *"Driver btrfs failed to remove"* ]]; then 257 | : # Ignore error because of https://circleci.com/docs/docker-btrfs-error/ 258 | else 259 | echo "$rm_output" 260 | exit $rm_exit_code 261 | fi 262 | fi 263 | 264 | exit $run_exit_code 265 | 266 | ################################################################################ 267 | # 268 | # This image is not intended to be run manually. 269 | # 270 | # To create a dockcross helper script for the 271 | # dockcross/linux-ppc64le:20230601-c2f5366 image, run: 272 | # 273 | # docker run --rm dockcross/linux-ppc64le:20230601-c2f5366 > dockcross-linux-ppc64le-20230601-c2f5366 274 | # chmod +x dockcross-linux-ppc64le-20230601-c2f5366 275 | # 276 | # You may then wish to move the dockcross script to your PATH. 277 | # 278 | ################################################################################ 279 | -------------------------------------------------------------------------------- /libwebp-jni/dockcross/dockcross-manylinux-x64: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DEFAULT_DOCKCROSS_IMAGE=dockcross/manylinux2010-x64:latest 4 | 5 | #------------------------------------------------------------------------------ 6 | # Helpers 7 | # 8 | err() { 9 | echo -e >&2 "ERROR: $*\n" 10 | } 11 | 12 | die() { 13 | err "$*" 14 | exit 1 15 | } 16 | 17 | has() { 18 | # eg. has command update 19 | local kind=$1 20 | local name=$2 21 | 22 | type -t $kind:$name | grep -q function 23 | } 24 | 25 | # If OCI_EXE is not already set, search for a container executor (OCI stands for "Open Container Initiative") 26 | if [ -z "$OCI_EXE" ]; then 27 | if which podman >/dev/null 2>/dev/null; then 28 | OCI_EXE=podman 29 | elif which docker >/dev/null 2>/dev/null; then 30 | OCI_EXE=docker 31 | else 32 | die "Cannot find a container executor. Search for docker and podman." 33 | fi 34 | fi 35 | 36 | #------------------------------------------------------------------------------ 37 | # Command handlers 38 | # 39 | command:update-image() { 40 | $OCI_EXE pull $FINAL_IMAGE 41 | } 42 | 43 | help:update-image() { 44 | echo "Pull the latest $FINAL_IMAGE ." 45 | } 46 | 47 | command:update-script() { 48 | if cmp -s <( $OCI_EXE run --rm $FINAL_IMAGE ) $0; then 49 | echo "$0 is up to date" 50 | else 51 | echo -n "Updating $0 ... " 52 | $OCI_EXE run --rm $FINAL_IMAGE > $0 && echo ok 53 | fi 54 | } 55 | 56 | help:update-script() { 57 | echo "Update $0 from $FINAL_IMAGE ." 58 | } 59 | 60 | command:update() { 61 | command:update-image 62 | command:update-script 63 | } 64 | 65 | help:update() { 66 | echo "Pull the latest $FINAL_IMAGE, and then update $0 from that." 67 | } 68 | 69 | command:help() { 70 | if [[ $# != 0 ]]; then 71 | if ! has command $1; then 72 | err \"$1\" is not an dockcross command 73 | command:help 74 | elif ! has help $1; then 75 | err No help found for \"$1\" 76 | else 77 | help:$1 78 | fi 79 | else 80 | cat >&2 < 99 | ENDHELP 100 | exit 1 101 | fi 102 | } 103 | 104 | #------------------------------------------------------------------------------ 105 | # Option processing 106 | # 107 | special_update_command='' 108 | while [[ $# != 0 ]]; do 109 | case $1 in 110 | 111 | --) 112 | shift 113 | break 114 | ;; 115 | 116 | --args|-a) 117 | ARG_ARGS="$2" 118 | shift 2 119 | ;; 120 | 121 | --config|-c) 122 | ARG_CONFIG="$2" 123 | shift 2 124 | ;; 125 | 126 | --image|-i) 127 | ARG_IMAGE="$2" 128 | shift 2 129 | ;; 130 | update|update-image|update-script) 131 | special_update_command=$1 132 | break 133 | ;; 134 | -*) 135 | err Unknown option \"$1\" 136 | command:help 137 | exit 138 | ;; 139 | 140 | *) 141 | break 142 | ;; 143 | 144 | esac 145 | done 146 | 147 | # The precedence for options is: 148 | # 1. command-line arguments 149 | # 2. environment variables 150 | # 3. defaults 151 | 152 | # Source the config file if it exists 153 | DEFAULT_DOCKCROSS_CONFIG=~/.dockcross 154 | FINAL_CONFIG=${ARG_CONFIG-${DOCKCROSS_CONFIG-$DEFAULT_DOCKCROSS_CONFIG}} 155 | 156 | [[ -f "$FINAL_CONFIG" ]] && source "$FINAL_CONFIG" 157 | 158 | # Set the docker image 159 | FINAL_IMAGE=${ARG_IMAGE-${DOCKCROSS_IMAGE-$DEFAULT_DOCKCROSS_IMAGE}} 160 | 161 | # Handle special update command 162 | if [ "$special_update_command" != "" ]; then 163 | case $special_update_command in 164 | 165 | update) 166 | command:update 167 | exit $? 168 | ;; 169 | 170 | update-image) 171 | command:update-image 172 | exit $? 173 | ;; 174 | 175 | update-script) 176 | command:update-script 177 | exit $? 178 | ;; 179 | 180 | esac 181 | fi 182 | 183 | # Set the docker run extra args (if any) 184 | FINAL_ARGS=${ARG_ARGS-${DOCKCROSS_ARGS}} 185 | 186 | # Bash on Ubuntu on Windows 187 | UBUNTU_ON_WINDOWS=$([ -e /proc/version ] && grep -l Microsoft /proc/version || echo "") 188 | # MSYS, Git Bash, etc. 189 | MSYS=$([ -e /proc/version ] && grep -l MINGW /proc/version || echo "") 190 | # CYGWIN 191 | CYGWIN=$([ -e /proc/version ] && grep -l CYGWIN /proc/version || echo "") 192 | 193 | if [ -z "$UBUNTU_ON_WINDOWS" -a -z "$MSYS" -a "$OCI_EXE" != "podman" ]; then 194 | USER_IDS=(-e BUILDER_UID="$( id -u )" -e BUILDER_GID="$( id -g )" -e BUILDER_USER="$( id -un )" -e BUILDER_GROUP="$( id -gn )") 195 | fi 196 | 197 | # Change the PWD when working in Docker on Windows 198 | if [ -n "$UBUNTU_ON_WINDOWS" ]; then 199 | WSL_ROOT="/mnt/" 200 | CFG_FILE=/etc/wsl.conf 201 | if [ -f "$CFG_FILE" ]; then 202 | CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g') 203 | eval "$CFG_CONTENT" 204 | if [ -n "$root" ]; then 205 | WSL_ROOT=$root 206 | fi 207 | fi 208 | HOST_PWD=`pwd -P` 209 | HOST_PWD=${HOST_PWD/$WSL_ROOT//} 210 | elif [ -n "$MSYS" ]; then 211 | HOST_PWD=$PWD 212 | HOST_PWD=${HOST_PWD/\//} 213 | HOST_PWD=${HOST_PWD/\//:\/} 214 | elif [ -n "$CYGWIN" ]; then 215 | for f in pwd readlink cygpath ; do 216 | test -n "$(type "${f}" )" || { echo >&2 "Missing functionality (${f}) (in cygwin)." ; exit 1 ; } ; 217 | done ; 218 | HOST_PWD="$( cygpath -w "$( readlink -f "$( pwd ;)" ; )" ; )" ; 219 | else 220 | HOST_PWD=$PWD 221 | [ -L $HOST_PWD ] && HOST_PWD=$(readlink $HOST_PWD) 222 | fi 223 | 224 | # Mount Additional Volumes 225 | if [ -z "$SSH_DIR" ]; then 226 | SSH_DIR="$HOME/.ssh" 227 | fi 228 | 229 | HOST_VOLUMES= 230 | if [ -e "$SSH_DIR" -a -z "$MSYS" ]; then 231 | if test -n "${CYGWIN}" ; then 232 | HOST_VOLUMES+="-v $(cygpath -w ${SSH_DIR} ; ):/home/$(id -un)/.ssh" ; 233 | else 234 | HOST_VOLUMES+="-v $SSH_DIR:/home/$(id -un)/.ssh" ; 235 | fi ; 236 | fi 237 | 238 | #------------------------------------------------------------------------------ 239 | # Now, finally, run the command in a container 240 | # 241 | TTY_ARGS= 242 | tty -s && [ -z "$MSYS" ] && TTY_ARGS=-ti 243 | CONTAINER_NAME=dockcross_$RANDOM 244 | $OCI_EXE run $TTY_ARGS --name $CONTAINER_NAME \ 245 | -v "$HOST_PWD":/work \ 246 | $HOST_VOLUMES \ 247 | "${USER_IDS[@]}" \ 248 | $FINAL_ARGS \ 249 | $FINAL_IMAGE "$@" 250 | run_exit_code=$? 251 | 252 | # Attempt to delete container 253 | rm_output=$($OCI_EXE rm -f $CONTAINER_NAME 2>&1) 254 | rm_exit_code=$? 255 | if [[ $rm_exit_code != 0 ]]; then 256 | if [[ "$CIRCLECI" == "true" ]] && [[ $rm_output == *"Driver btrfs failed to remove"* ]]; then 257 | : # Ignore error because of https://circleci.com/docs/docker-btrfs-error/ 258 | else 259 | echo "$rm_output" 260 | exit $rm_exit_code 261 | fi 262 | fi 263 | 264 | exit $run_exit_code 265 | 266 | ################################################################################ 267 | # 268 | # This image is not intended to be run manually. 269 | # 270 | # To create a dockcross helper script for the 271 | # dockcross/manylinux2010-x64:latest image, run: 272 | # 273 | # docker run --rm dockcross/manylinux2010-x64:latest > dockcross-manylinux2010-x64-latest 274 | # chmod +x dockcross-manylinux2010-x64-latest 275 | # 276 | # You may then wish to move the dockcross script to your PATH. 277 | # 278 | ################################################################################ 279 | -------------------------------------------------------------------------------- /libwebp-jni/dockcross/dockcross-manylinux-x86: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DEFAULT_DOCKCROSS_IMAGE=dockcross/manylinux2010-x86:latest 4 | 5 | #------------------------------------------------------------------------------ 6 | # Helpers 7 | # 8 | err() { 9 | echo -e >&2 "ERROR: $*\n" 10 | } 11 | 12 | die() { 13 | err "$*" 14 | exit 1 15 | } 16 | 17 | has() { 18 | # eg. has command update 19 | local kind=$1 20 | local name=$2 21 | 22 | type -t $kind:$name | grep -q function 23 | } 24 | 25 | # If OCI_EXE is not already set, search for a container executor (OCI stands for "Open Container Initiative") 26 | if [ -z "$OCI_EXE" ]; then 27 | if which podman >/dev/null 2>/dev/null; then 28 | OCI_EXE=podman 29 | elif which docker >/dev/null 2>/dev/null; then 30 | OCI_EXE=docker 31 | else 32 | die "Cannot find a container executor. Search for docker and podman." 33 | fi 34 | fi 35 | 36 | #------------------------------------------------------------------------------ 37 | # Command handlers 38 | # 39 | command:update-image() { 40 | $OCI_EXE pull $FINAL_IMAGE 41 | } 42 | 43 | help:update-image() { 44 | echo "Pull the latest $FINAL_IMAGE ." 45 | } 46 | 47 | command:update-script() { 48 | if cmp -s <( $OCI_EXE run --rm $FINAL_IMAGE ) $0; then 49 | echo "$0 is up to date" 50 | else 51 | echo -n "Updating $0 ... " 52 | $OCI_EXE run --rm $FINAL_IMAGE > $0 && echo ok 53 | fi 54 | } 55 | 56 | help:update-script() { 57 | echo "Update $0 from $FINAL_IMAGE ." 58 | } 59 | 60 | command:update() { 61 | command:update-image 62 | command:update-script 63 | } 64 | 65 | help:update() { 66 | echo "Pull the latest $FINAL_IMAGE, and then update $0 from that." 67 | } 68 | 69 | command:help() { 70 | if [[ $# != 0 ]]; then 71 | if ! has command $1; then 72 | err \"$1\" is not an dockcross command 73 | command:help 74 | elif ! has help $1; then 75 | err No help found for \"$1\" 76 | else 77 | help:$1 78 | fi 79 | else 80 | cat >&2 < 99 | ENDHELP 100 | exit 1 101 | fi 102 | } 103 | 104 | #------------------------------------------------------------------------------ 105 | # Option processing 106 | # 107 | special_update_command='' 108 | while [[ $# != 0 ]]; do 109 | case $1 in 110 | 111 | --) 112 | shift 113 | break 114 | ;; 115 | 116 | --args|-a) 117 | ARG_ARGS="$2" 118 | shift 2 119 | ;; 120 | 121 | --config|-c) 122 | ARG_CONFIG="$2" 123 | shift 2 124 | ;; 125 | 126 | --image|-i) 127 | ARG_IMAGE="$2" 128 | shift 2 129 | ;; 130 | update|update-image|update-script) 131 | special_update_command=$1 132 | break 133 | ;; 134 | -*) 135 | err Unknown option \"$1\" 136 | command:help 137 | exit 138 | ;; 139 | 140 | *) 141 | break 142 | ;; 143 | 144 | esac 145 | done 146 | 147 | # The precedence for options is: 148 | # 1. command-line arguments 149 | # 2. environment variables 150 | # 3. defaults 151 | 152 | # Source the config file if it exists 153 | DEFAULT_DOCKCROSS_CONFIG=~/.dockcross 154 | FINAL_CONFIG=${ARG_CONFIG-${DOCKCROSS_CONFIG-$DEFAULT_DOCKCROSS_CONFIG}} 155 | 156 | [[ -f "$FINAL_CONFIG" ]] && source "$FINAL_CONFIG" 157 | 158 | # Set the docker image 159 | FINAL_IMAGE=${ARG_IMAGE-${DOCKCROSS_IMAGE-$DEFAULT_DOCKCROSS_IMAGE}} 160 | 161 | # Handle special update command 162 | if [ "$special_update_command" != "" ]; then 163 | case $special_update_command in 164 | 165 | update) 166 | command:update 167 | exit $? 168 | ;; 169 | 170 | update-image) 171 | command:update-image 172 | exit $? 173 | ;; 174 | 175 | update-script) 176 | command:update-script 177 | exit $? 178 | ;; 179 | 180 | esac 181 | fi 182 | 183 | # Set the docker run extra args (if any) 184 | FINAL_ARGS=${ARG_ARGS-${DOCKCROSS_ARGS}} 185 | 186 | # Bash on Ubuntu on Windows 187 | UBUNTU_ON_WINDOWS=$([ -e /proc/version ] && grep -l Microsoft /proc/version || echo "") 188 | # MSYS, Git Bash, etc. 189 | MSYS=$([ -e /proc/version ] && grep -l MINGW /proc/version || echo "") 190 | # CYGWIN 191 | CYGWIN=$([ -e /proc/version ] && grep -l CYGWIN /proc/version || echo "") 192 | 193 | if [ -z "$UBUNTU_ON_WINDOWS" -a -z "$MSYS" -a "$OCI_EXE" != "podman" ]; then 194 | USER_IDS=(-e BUILDER_UID="$( id -u )" -e BUILDER_GID="$( id -g )" -e BUILDER_USER="$( id -un )" -e BUILDER_GROUP="$( id -gn )") 195 | fi 196 | 197 | # Change the PWD when working in Docker on Windows 198 | if [ -n "$UBUNTU_ON_WINDOWS" ]; then 199 | WSL_ROOT="/mnt/" 200 | CFG_FILE=/etc/wsl.conf 201 | if [ -f "$CFG_FILE" ]; then 202 | CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g') 203 | eval "$CFG_CONTENT" 204 | if [ -n "$root" ]; then 205 | WSL_ROOT=$root 206 | fi 207 | fi 208 | HOST_PWD=`pwd -P` 209 | HOST_PWD=${HOST_PWD/$WSL_ROOT//} 210 | elif [ -n "$MSYS" ]; then 211 | HOST_PWD=$PWD 212 | HOST_PWD=${HOST_PWD/\//} 213 | HOST_PWD=${HOST_PWD/\//:\/} 214 | elif [ -n "$CYGWIN" ]; then 215 | for f in pwd readlink cygpath ; do 216 | test -n "$(type "${f}" )" || { echo >&2 "Missing functionality (${f}) (in cygwin)." ; exit 1 ; } ; 217 | done ; 218 | HOST_PWD="$( cygpath -w "$( readlink -f "$( pwd ;)" ; )" ; )" ; 219 | else 220 | HOST_PWD=$PWD 221 | [ -L $HOST_PWD ] && HOST_PWD=$(readlink $HOST_PWD) 222 | fi 223 | 224 | # Mount Additional Volumes 225 | if [ -z "$SSH_DIR" ]; then 226 | SSH_DIR="$HOME/.ssh" 227 | fi 228 | 229 | HOST_VOLUMES= 230 | if [ -e "$SSH_DIR" -a -z "$MSYS" ]; then 231 | if test -n "${CYGWIN}" ; then 232 | HOST_VOLUMES+="-v $(cygpath -w ${SSH_DIR} ; ):/home/$(id -un)/.ssh" ; 233 | else 234 | HOST_VOLUMES+="-v $SSH_DIR:/home/$(id -un)/.ssh" ; 235 | fi ; 236 | fi 237 | 238 | #------------------------------------------------------------------------------ 239 | # Now, finally, run the command in a container 240 | # 241 | TTY_ARGS= 242 | tty -s && [ -z "$MSYS" ] && TTY_ARGS=-ti 243 | CONTAINER_NAME=dockcross_$RANDOM 244 | $OCI_EXE run $TTY_ARGS --name $CONTAINER_NAME \ 245 | -v "$HOST_PWD":/work \ 246 | $HOST_VOLUMES \ 247 | "${USER_IDS[@]}" \ 248 | $FINAL_ARGS \ 249 | $FINAL_IMAGE "$@" 250 | run_exit_code=$? 251 | 252 | # Attempt to delete container 253 | rm_output=$($OCI_EXE rm -f $CONTAINER_NAME 2>&1) 254 | rm_exit_code=$? 255 | if [[ $rm_exit_code != 0 ]]; then 256 | if [[ "$CIRCLECI" == "true" ]] && [[ $rm_output == *"Driver btrfs failed to remove"* ]]; then 257 | : # Ignore error because of https://circleci.com/docs/docker-btrfs-error/ 258 | else 259 | echo "$rm_output" 260 | exit $rm_exit_code 261 | fi 262 | fi 263 | 264 | exit $run_exit_code 265 | 266 | ################################################################################ 267 | # 268 | # This image is not intended to be run manually. 269 | # 270 | # To create a dockcross helper script for the 271 | # dockcross/manylinux2010-x86:latest image, run: 272 | # 273 | # docker run --rm dockcross/manylinux2010-x86:latest > dockcross-manylinux2010-x86-latest 274 | # chmod +x dockcross-manylinux2010-x86-latest 275 | # 276 | # You may then wish to move the dockcross script to your PATH. 277 | # 278 | ################################################################################ 279 | -------------------------------------------------------------------------------- /libwebp-jni/dockcross/dockcross-windows-static-x64: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DEFAULT_DOCKCROSS_IMAGE=dockcross/windows-static-x64:latest 4 | 5 | #------------------------------------------------------------------------------ 6 | # Helpers 7 | # 8 | err() { 9 | echo -e >&2 "ERROR: $*\n" 10 | } 11 | 12 | die() { 13 | err "$*" 14 | exit 1 15 | } 16 | 17 | has() { 18 | # eg. has command update 19 | local kind=$1 20 | local name=$2 21 | 22 | type -t $kind:$name | grep -q function 23 | } 24 | 25 | # If OCI_EXE is not already set, search for a container executor (OCI stands for "Open Container Initiative") 26 | if [ -z "$OCI_EXE" ]; then 27 | if which podman >/dev/null 2>/dev/null; then 28 | OCI_EXE=podman 29 | elif which docker >/dev/null 2>/dev/null; then 30 | OCI_EXE=docker 31 | else 32 | die "Cannot find a container executor. Search for docker and podman." 33 | fi 34 | fi 35 | 36 | #------------------------------------------------------------------------------ 37 | # Command handlers 38 | # 39 | command:update-image() { 40 | $OCI_EXE pull $FINAL_IMAGE 41 | } 42 | 43 | help:update-image() { 44 | echo "Pull the latest $FINAL_IMAGE ." 45 | } 46 | 47 | command:update-script() { 48 | if cmp -s <( $OCI_EXE run --rm $FINAL_IMAGE ) $0; then 49 | echo "$0 is up to date" 50 | else 51 | echo -n "Updating $0 ... " 52 | $OCI_EXE run --rm $FINAL_IMAGE > $0 && echo ok 53 | fi 54 | } 55 | 56 | help:update-script() { 57 | echo "Update $0 from $FINAL_IMAGE ." 58 | } 59 | 60 | command:update() { 61 | command:update-image 62 | command:update-script 63 | } 64 | 65 | help:update() { 66 | echo "Pull the latest $FINAL_IMAGE, and then update $0 from that." 67 | } 68 | 69 | command:help() { 70 | if [[ $# != 0 ]]; then 71 | if ! has command $1; then 72 | err \"$1\" is not an dockcross command 73 | command:help 74 | elif ! has help $1; then 75 | err No help found for \"$1\" 76 | else 77 | help:$1 78 | fi 79 | else 80 | cat >&2 < 99 | ENDHELP 100 | exit 1 101 | fi 102 | } 103 | 104 | #------------------------------------------------------------------------------ 105 | # Option processing 106 | # 107 | special_update_command='' 108 | while [[ $# != 0 ]]; do 109 | case $1 in 110 | 111 | --) 112 | shift 113 | break 114 | ;; 115 | 116 | --args|-a) 117 | ARG_ARGS="$2" 118 | shift 2 119 | ;; 120 | 121 | --config|-c) 122 | ARG_CONFIG="$2" 123 | shift 2 124 | ;; 125 | 126 | --image|-i) 127 | ARG_IMAGE="$2" 128 | shift 2 129 | ;; 130 | update|update-image|update-script) 131 | special_update_command=$1 132 | break 133 | ;; 134 | -*) 135 | err Unknown option \"$1\" 136 | command:help 137 | exit 138 | ;; 139 | 140 | *) 141 | break 142 | ;; 143 | 144 | esac 145 | done 146 | 147 | # The precedence for options is: 148 | # 1. command-line arguments 149 | # 2. environment variables 150 | # 3. defaults 151 | 152 | # Source the config file if it exists 153 | DEFAULT_DOCKCROSS_CONFIG=~/.dockcross 154 | FINAL_CONFIG=${ARG_CONFIG-${DOCKCROSS_CONFIG-$DEFAULT_DOCKCROSS_CONFIG}} 155 | 156 | [[ -f "$FINAL_CONFIG" ]] && source "$FINAL_CONFIG" 157 | 158 | # Set the docker image 159 | FINAL_IMAGE=${ARG_IMAGE-${DOCKCROSS_IMAGE-$DEFAULT_DOCKCROSS_IMAGE}} 160 | 161 | # Handle special update command 162 | if [ "$special_update_command" != "" ]; then 163 | case $special_update_command in 164 | 165 | update) 166 | command:update 167 | exit $? 168 | ;; 169 | 170 | update-image) 171 | command:update-image 172 | exit $? 173 | ;; 174 | 175 | update-script) 176 | command:update-script 177 | exit $? 178 | ;; 179 | 180 | esac 181 | fi 182 | 183 | # Set the docker run extra args (if any) 184 | FINAL_ARGS=${ARG_ARGS-${DOCKCROSS_ARGS}} 185 | 186 | # Bash on Ubuntu on Windows 187 | UBUNTU_ON_WINDOWS=$([ -e /proc/version ] && grep -l Microsoft /proc/version || echo "") 188 | # MSYS, Git Bash, etc. 189 | MSYS=$([ -e /proc/version ] && grep -l MINGW /proc/version || echo "") 190 | # CYGWIN 191 | CYGWIN=$([ -e /proc/version ] && grep -l CYGWIN /proc/version || echo "") 192 | 193 | if [ -z "$UBUNTU_ON_WINDOWS" -a -z "$MSYS" -a "$OCI_EXE" != "podman" ]; then 194 | USER_IDS=(-e BUILDER_UID="$( id -u )" -e BUILDER_GID="$( id -g )" -e BUILDER_USER="$( id -un )" -e BUILDER_GROUP="$( id -gn )") 195 | fi 196 | 197 | # Change the PWD when working in Docker on Windows 198 | if [ -n "$UBUNTU_ON_WINDOWS" ]; then 199 | WSL_ROOT="/mnt/" 200 | CFG_FILE=/etc/wsl.conf 201 | if [ -f "$CFG_FILE" ]; then 202 | CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g') 203 | eval "$CFG_CONTENT" 204 | if [ -n "$root" ]; then 205 | WSL_ROOT=$root 206 | fi 207 | fi 208 | HOST_PWD=`pwd -P` 209 | HOST_PWD=${HOST_PWD/$WSL_ROOT//} 210 | elif [ -n "$MSYS" ]; then 211 | HOST_PWD=$PWD 212 | HOST_PWD=${HOST_PWD/\//} 213 | HOST_PWD=${HOST_PWD/\//:\/} 214 | elif [ -n "$CYGWIN" ]; then 215 | for f in pwd readlink cygpath ; do 216 | test -n "$(type "${f}" )" || { echo >&2 "Missing functionality (${f}) (in cygwin)." ; exit 1 ; } ; 217 | done ; 218 | HOST_PWD="$( cygpath -w "$( readlink -f "$( pwd ;)" ; )" ; )" ; 219 | else 220 | HOST_PWD=$PWD 221 | [ -L $HOST_PWD ] && HOST_PWD=$(readlink $HOST_PWD) 222 | fi 223 | 224 | # Mount Additional Volumes 225 | if [ -z "$SSH_DIR" ]; then 226 | SSH_DIR="$HOME/.ssh" 227 | fi 228 | 229 | HOST_VOLUMES= 230 | if [ -e "$SSH_DIR" -a -z "$MSYS" ]; then 231 | if test -n "${CYGWIN}" ; then 232 | HOST_VOLUMES+="-v $(cygpath -w ${SSH_DIR} ; ):/home/$(id -un)/.ssh" ; 233 | else 234 | HOST_VOLUMES+="-v $SSH_DIR:/home/$(id -un)/.ssh" ; 235 | fi ; 236 | fi 237 | 238 | #------------------------------------------------------------------------------ 239 | # Now, finally, run the command in a container 240 | # 241 | TTY_ARGS= 242 | tty -s && [ -z "$MSYS" ] && TTY_ARGS=-ti 243 | CONTAINER_NAME=dockcross_$RANDOM 244 | $OCI_EXE run $TTY_ARGS --name $CONTAINER_NAME \ 245 | -v "$HOST_PWD":/work \ 246 | $HOST_VOLUMES \ 247 | "${USER_IDS[@]}" \ 248 | $FINAL_ARGS \ 249 | $FINAL_IMAGE "$@" 250 | run_exit_code=$? 251 | 252 | # Attempt to delete container 253 | rm_output=$($OCI_EXE rm -f $CONTAINER_NAME 2>&1) 254 | rm_exit_code=$? 255 | if [[ $rm_exit_code != 0 ]]; then 256 | if [[ "$CIRCLECI" == "true" ]] && [[ $rm_output == *"Driver btrfs failed to remove"* ]]; then 257 | : # Ignore error because of https://circleci.com/docs/docker-btrfs-error/ 258 | else 259 | echo "$rm_output" 260 | exit $rm_exit_code 261 | fi 262 | fi 263 | 264 | exit $run_exit_code 265 | 266 | ################################################################################ 267 | # 268 | # This image is not intended to be run manually. 269 | # 270 | # To create a dockcross helper script for the 271 | # dockcross/windows-static-x64:20230601-c2f5366 image, run: 272 | # 273 | # docker run --rm dockcross/windows-static-x64:20230601-c2f5366 > dockcross-windows-static-x64-20230601-c2f5366 274 | # chmod +x dockcross-windows-static-x64-20230601-c2f5366 275 | # 276 | # You may then wish to move the dockcross script to your PATH. 277 | # 278 | ################################################################################ 279 | -------------------------------------------------------------------------------- /libwebp-jni/dockcross/dockcross-windows-static-x86: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DEFAULT_DOCKCROSS_IMAGE=dockcross/windows-static-x86:latest 4 | 5 | #------------------------------------------------------------------------------ 6 | # Helpers 7 | # 8 | err() { 9 | echo -e >&2 "ERROR: $*\n" 10 | } 11 | 12 | die() { 13 | err "$*" 14 | exit 1 15 | } 16 | 17 | has() { 18 | # eg. has command update 19 | local kind=$1 20 | local name=$2 21 | 22 | type -t $kind:$name | grep -q function 23 | } 24 | 25 | # If OCI_EXE is not already set, search for a container executor (OCI stands for "Open Container Initiative") 26 | if [ -z "$OCI_EXE" ]; then 27 | if which podman >/dev/null 2>/dev/null; then 28 | OCI_EXE=podman 29 | elif which docker >/dev/null 2>/dev/null; then 30 | OCI_EXE=docker 31 | else 32 | die "Cannot find a container executor. Search for docker and podman." 33 | fi 34 | fi 35 | 36 | #------------------------------------------------------------------------------ 37 | # Command handlers 38 | # 39 | command:update-image() { 40 | $OCI_EXE pull $FINAL_IMAGE 41 | } 42 | 43 | help:update-image() { 44 | echo "Pull the latest $FINAL_IMAGE ." 45 | } 46 | 47 | command:update-script() { 48 | if cmp -s <( $OCI_EXE run --rm $FINAL_IMAGE ) $0; then 49 | echo "$0 is up to date" 50 | else 51 | echo -n "Updating $0 ... " 52 | $OCI_EXE run --rm $FINAL_IMAGE > $0 && echo ok 53 | fi 54 | } 55 | 56 | help:update-script() { 57 | echo "Update $0 from $FINAL_IMAGE ." 58 | } 59 | 60 | command:update() { 61 | command:update-image 62 | command:update-script 63 | } 64 | 65 | help:update() { 66 | echo "Pull the latest $FINAL_IMAGE, and then update $0 from that." 67 | } 68 | 69 | command:help() { 70 | if [[ $# != 0 ]]; then 71 | if ! has command $1; then 72 | err \"$1\" is not an dockcross command 73 | command:help 74 | elif ! has help $1; then 75 | err No help found for \"$1\" 76 | else 77 | help:$1 78 | fi 79 | else 80 | cat >&2 < 99 | ENDHELP 100 | exit 1 101 | fi 102 | } 103 | 104 | #------------------------------------------------------------------------------ 105 | # Option processing 106 | # 107 | special_update_command='' 108 | while [[ $# != 0 ]]; do 109 | case $1 in 110 | 111 | --) 112 | shift 113 | break 114 | ;; 115 | 116 | --args|-a) 117 | ARG_ARGS="$2" 118 | shift 2 119 | ;; 120 | 121 | --config|-c) 122 | ARG_CONFIG="$2" 123 | shift 2 124 | ;; 125 | 126 | --image|-i) 127 | ARG_IMAGE="$2" 128 | shift 2 129 | ;; 130 | update|update-image|update-script) 131 | special_update_command=$1 132 | break 133 | ;; 134 | -*) 135 | err Unknown option \"$1\" 136 | command:help 137 | exit 138 | ;; 139 | 140 | *) 141 | break 142 | ;; 143 | 144 | esac 145 | done 146 | 147 | # The precedence for options is: 148 | # 1. command-line arguments 149 | # 2. environment variables 150 | # 3. defaults 151 | 152 | # Source the config file if it exists 153 | DEFAULT_DOCKCROSS_CONFIG=~/.dockcross 154 | FINAL_CONFIG=${ARG_CONFIG-${DOCKCROSS_CONFIG-$DEFAULT_DOCKCROSS_CONFIG}} 155 | 156 | [[ -f "$FINAL_CONFIG" ]] && source "$FINAL_CONFIG" 157 | 158 | # Set the docker image 159 | FINAL_IMAGE=${ARG_IMAGE-${DOCKCROSS_IMAGE-$DEFAULT_DOCKCROSS_IMAGE}} 160 | 161 | # Handle special update command 162 | if [ "$special_update_command" != "" ]; then 163 | case $special_update_command in 164 | 165 | update) 166 | command:update 167 | exit $? 168 | ;; 169 | 170 | update-image) 171 | command:update-image 172 | exit $? 173 | ;; 174 | 175 | update-script) 176 | command:update-script 177 | exit $? 178 | ;; 179 | 180 | esac 181 | fi 182 | 183 | # Set the docker run extra args (if any) 184 | FINAL_ARGS=${ARG_ARGS-${DOCKCROSS_ARGS}} 185 | 186 | # Bash on Ubuntu on Windows 187 | UBUNTU_ON_WINDOWS=$([ -e /proc/version ] && grep -l Microsoft /proc/version || echo "") 188 | # MSYS, Git Bash, etc. 189 | MSYS=$([ -e /proc/version ] && grep -l MINGW /proc/version || echo "") 190 | # CYGWIN 191 | CYGWIN=$([ -e /proc/version ] && grep -l CYGWIN /proc/version || echo "") 192 | 193 | if [ -z "$UBUNTU_ON_WINDOWS" -a -z "$MSYS" -a "$OCI_EXE" != "podman" ]; then 194 | USER_IDS=(-e BUILDER_UID="$( id -u )" -e BUILDER_GID="$( id -g )" -e BUILDER_USER="$( id -un )" -e BUILDER_GROUP="$( id -gn )") 195 | fi 196 | 197 | # Change the PWD when working in Docker on Windows 198 | if [ -n "$UBUNTU_ON_WINDOWS" ]; then 199 | WSL_ROOT="/mnt/" 200 | CFG_FILE=/etc/wsl.conf 201 | if [ -f "$CFG_FILE" ]; then 202 | CFG_CONTENT=$(cat $CFG_FILE | sed -r '/[^=]+=[^=]+/!d' | sed -r 's/\s+=\s/=/g') 203 | eval "$CFG_CONTENT" 204 | if [ -n "$root" ]; then 205 | WSL_ROOT=$root 206 | fi 207 | fi 208 | HOST_PWD=`pwd -P` 209 | HOST_PWD=${HOST_PWD/$WSL_ROOT//} 210 | elif [ -n "$MSYS" ]; then 211 | HOST_PWD=$PWD 212 | HOST_PWD=${HOST_PWD/\//} 213 | HOST_PWD=${HOST_PWD/\//:\/} 214 | elif [ -n "$CYGWIN" ]; then 215 | for f in pwd readlink cygpath ; do 216 | test -n "$(type "${f}" )" || { echo >&2 "Missing functionality (${f}) (in cygwin)." ; exit 1 ; } ; 217 | done ; 218 | HOST_PWD="$( cygpath -w "$( readlink -f "$( pwd ;)" ; )" ; )" ; 219 | else 220 | HOST_PWD=$PWD 221 | [ -L $HOST_PWD ] && HOST_PWD=$(readlink $HOST_PWD) 222 | fi 223 | 224 | # Mount Additional Volumes 225 | if [ -z "$SSH_DIR" ]; then 226 | SSH_DIR="$HOME/.ssh" 227 | fi 228 | 229 | HOST_VOLUMES= 230 | if [ -e "$SSH_DIR" -a -z "$MSYS" ]; then 231 | if test -n "${CYGWIN}" ; then 232 | HOST_VOLUMES+="-v $(cygpath -w ${SSH_DIR} ; ):/home/$(id -un)/.ssh" ; 233 | else 234 | HOST_VOLUMES+="-v $SSH_DIR:/home/$(id -un)/.ssh" ; 235 | fi ; 236 | fi 237 | 238 | #------------------------------------------------------------------------------ 239 | # Now, finally, run the command in a container 240 | # 241 | TTY_ARGS= 242 | tty -s && [ -z "$MSYS" ] && TTY_ARGS=-ti 243 | CONTAINER_NAME=dockcross_$RANDOM 244 | $OCI_EXE run $TTY_ARGS --name $CONTAINER_NAME \ 245 | -v "$HOST_PWD":/work \ 246 | $HOST_VOLUMES \ 247 | "${USER_IDS[@]}" \ 248 | $FINAL_ARGS \ 249 | $FINAL_IMAGE "$@" 250 | run_exit_code=$? 251 | 252 | # Attempt to delete container 253 | rm_output=$($OCI_EXE rm -f $CONTAINER_NAME 2>&1) 254 | rm_exit_code=$? 255 | if [[ $rm_exit_code != 0 ]]; then 256 | if [[ "$CIRCLECI" == "true" ]] && [[ $rm_output == *"Driver btrfs failed to remove"* ]]; then 257 | : # Ignore error because of https://circleci.com/docs/docker-btrfs-error/ 258 | else 259 | echo "$rm_output" 260 | exit $rm_exit_code 261 | fi 262 | fi 263 | 264 | exit $run_exit_code 265 | 266 | ################################################################################ 267 | # 268 | # This image is not intended to be run manually. 269 | # 270 | # To create a dockcross helper script for the 271 | # dockcross/windows-static-x86:20230601-c2f5366 image, run: 272 | # 273 | # docker run --rm dockcross/windows-static-x86:20230601-c2f5366 > dockcross-windows-static-x86-20230601-c2f5366 274 | # chmod +x dockcross-windows-static-x86-20230601-c2f5366 275 | # 276 | # You may then wish to move the dockcross script to your PATH. 277 | # 278 | ################################################################################ 279 | -------------------------------------------------------------------------------- /libwebp-jni/multiarch-darwin.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Darwin) 2 | set(CMAKE_SYSTEM_VERSION 11.3) 3 | set(CMAKE_FIND_ROOT_PATH $ENV{CROSS_ROOT}) 4 | set(CMAKE_C_COMPILER cc) 5 | set(CMAKE_CXX_COMPILER c++) 6 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 7 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY FIRST) 8 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE FIRST) 9 | set(CMAKE_FIND_FRAMEWORK FIRST) 10 | 11 | set(CMAKE_OSX_SYSROOT_PATH /usr/osxcross/SDK/MacOSX11.3.sdk) 12 | set(CMAKE_OSX_SYSROOT ${CMAKE_OSX_SYSROOT_PATH}) 13 | list(APPEND CMAKE_SYSTEM_FRAMEWORK_PATH 14 | ${CMAKE_OSX_SYSROOT_PATH}/Library/Frameworks 15 | ${CMAKE_OSX_SYSROOT_PATH}/Network/Library/Frameworks 16 | ${CMAKE_OSX_SYSROOT_PATH}/System/Library/Frameworks 17 | ) 18 | -------------------------------------------------------------------------------- /libwebp-jni/src/main/c/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set( 2 | WEBP_HOME "${CMAKE_SOURCE_DIR}/libwebp" 3 | CACHE FILEPATH "libwebp source directory" 4 | ) 5 | 6 | set( 7 | JNI_OBJS 8 | ${CMAKE_CURRENT_SOURCE_DIR}/webp-imageio.c 9 | ) 10 | 11 | add_library( webp-imageio SHARED ${JNI_OBJS} ) 12 | include_directories( "${WEBP_HOME}/src" ) 13 | target_link_libraries( webp-imageio webp ) 14 | 15 | set( 16 | JNI_INCLUDE_DIRS 17 | ${CMAKE_CURRENT_SOURCE_DIR}/jni 18 | ) 19 | set( 20 | JNI_MD_INCLUDE_DIRS 21 | ${JNI_INCLUDE_DIRS}/unix 22 | ) 23 | 24 | if ( WIN32 ) 25 | set( 26 | JNI_MD_INCLUDE_DIRS 27 | ${JNI_INCLUDE_DIRS}/windows 28 | ) 29 | endif() 30 | 31 | if ( APPLE ) 32 | set( 33 | JNI_MD_INCLUDE_DIRS 34 | ${JNI_INCLUDE_DIRS}/darwin 35 | ) 36 | endif() 37 | 38 | include_directories( ${JNI_INCLUDE_DIRS} ) 39 | include_directories( ${JNI_MD_INCLUDE_DIRS} ) 40 | 41 | if( NOT MSVC ) 42 | target_compile_options( webp-imageio PRIVATE 43 | -Wextra 44 | -Wold-style-definition 45 | -Wmissing-prototypes 46 | -Wmissing-declarations 47 | -Wdeclaration-after-statement 48 | -Wshadow 49 | ) 50 | endif() 51 | 52 | if ( WIN32 ) 53 | # Strip 'lib' prefix when compiling for windows 54 | set_target_properties ( webp-imageio PROPERTIES PREFIX "" ) 55 | 56 | if( NOT MSVC ) 57 | set_target_properties( webp-imageio PROPERTIES LINK_FLAGS "-Wl,--kill-at") 58 | endif() 59 | endif() 60 | 61 | if ( APPLE ) 62 | set_target_properties( webp-imageio PROPERTIES MACOSX_RPATH OFF ) 63 | endif() 64 | -------------------------------------------------------------------------------- /libwebp-jni/src/main/c/com_luciad_imageio_webp_WebP.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | /* Header for class com_luciad_imageio_webp_WebP */ 4 | 5 | #ifndef _Included_com_luciad_imageio_webp_WebP 6 | #define _Included_com_luciad_imageio_webp_WebP 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | /* 11 | * Class: com_luciad_imageio_webp_WebP 12 | * Method: decode 13 | * Signature: (J[BII[IZ)[I 14 | */ 15 | JNIEXPORT jintArray JNICALL Java_com_luciad_imageio_webp_WebP_decode 16 | (JNIEnv *, jclass, jlong, jbyteArray, jint, jint, jintArray, jboolean); 17 | 18 | /* 19 | * Class: com_luciad_imageio_webp_WebP 20 | * Method: getInfo 21 | * Signature: ([BII[I)I 22 | */ 23 | JNIEXPORT jint JNICALL Java_com_luciad_imageio_webp_WebP_getInfo 24 | (JNIEnv *, jclass, jbyteArray, jint, jint, jintArray); 25 | 26 | /* 27 | * Class: com_luciad_imageio_webp_WebP 28 | * Method: encodeRGBA 29 | * Signature: (J[BIII)[B 30 | */ 31 | JNIEXPORT jbyteArray JNICALL Java_com_luciad_imageio_webp_WebP_encodeRGBA 32 | (JNIEnv *, jclass, jlong, jbyteArray, jint, jint, jint); 33 | 34 | /* 35 | * Class: com_luciad_imageio_webp_WebP 36 | * Method: encodeRGB 37 | * Signature: (J[BIII)[B 38 | */ 39 | JNIEXPORT jbyteArray JNICALL Java_com_luciad_imageio_webp_WebP_encodeRGB 40 | (JNIEnv *, jclass, jlong, jbyteArray, jint, jint, jint); 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | #endif 46 | -------------------------------------------------------------------------------- /libwebp-jni/src/main/c/com_luciad_imageio_webp_WebPDecoderOptions.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | /* Header for class com_luciad_imageio_webp_WebPDecoderOptions */ 4 | 5 | #ifndef _Included_com_luciad_imageio_webp_WebPDecoderOptions 6 | #define _Included_com_luciad_imageio_webp_WebPDecoderOptions 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | /* 11 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 12 | * Method: createDecoderOptions 13 | * Signature: ()J 14 | */ 15 | JNIEXPORT jlong JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_createDecoderOptions 16 | (JNIEnv *, jclass); 17 | 18 | /* 19 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 20 | * Method: deleteDecoderOptions 21 | * Signature: (J)V 22 | */ 23 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_deleteDecoderOptions 24 | (JNIEnv *, jclass, jlong); 25 | 26 | /* 27 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 28 | * Method: getBypassFiltering 29 | * Signature: (J)Z 30 | */ 31 | JNIEXPORT jboolean JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_getBypassFiltering 32 | (JNIEnv *, jclass, jlong); 33 | 34 | /* 35 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 36 | * Method: setBypassFiltering 37 | * Signature: (JZ)V 38 | */ 39 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_setBypassFiltering 40 | (JNIEnv *, jclass, jlong, jboolean); 41 | 42 | /* 43 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 44 | * Method: getNoFancyUpsampling 45 | * Signature: (J)Z 46 | */ 47 | JNIEXPORT jboolean JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_getNoFancyUpsampling 48 | (JNIEnv *, jclass, jlong); 49 | 50 | /* 51 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 52 | * Method: setNoFancyUpsampling 53 | * Signature: (JZ)V 54 | */ 55 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_setNoFancyUpsampling 56 | (JNIEnv *, jclass, jlong, jboolean); 57 | 58 | /* 59 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 60 | * Method: getUseCropping 61 | * Signature: (J)Z 62 | */ 63 | JNIEXPORT jboolean JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_getUseCropping 64 | (JNIEnv *, jclass, jlong); 65 | 66 | /* 67 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 68 | * Method: getCropLeft 69 | * Signature: (J)I 70 | */ 71 | JNIEXPORT jint JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_getCropLeft 72 | (JNIEnv *, jclass, jlong); 73 | 74 | /* 75 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 76 | * Method: setCropLeft 77 | * Signature: (JI)V 78 | */ 79 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_setCropLeft 80 | (JNIEnv *, jclass, jlong, jint); 81 | 82 | /* 83 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 84 | * Method: getCropTop 85 | * Signature: (J)I 86 | */ 87 | JNIEXPORT jint JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_getCropTop 88 | (JNIEnv *, jclass, jlong); 89 | 90 | /* 91 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 92 | * Method: setCropTop 93 | * Signature: (JI)V 94 | */ 95 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_setCropTop 96 | (JNIEnv *, jclass, jlong, jint); 97 | 98 | /* 99 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 100 | * Method: setUseCropping 101 | * Signature: (JZ)V 102 | */ 103 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_setUseCropping 104 | (JNIEnv *, jclass, jlong, jboolean); 105 | 106 | /* 107 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 108 | * Method: getCropWidth 109 | * Signature: (J)I 110 | */ 111 | JNIEXPORT jint JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_getCropWidth 112 | (JNIEnv *, jclass, jlong); 113 | 114 | /* 115 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 116 | * Method: setCropWidth 117 | * Signature: (JI)V 118 | */ 119 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_setCropWidth 120 | (JNIEnv *, jclass, jlong, jint); 121 | 122 | /* 123 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 124 | * Method: getCropHeight 125 | * Signature: (J)I 126 | */ 127 | JNIEXPORT jint JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_getCropHeight 128 | (JNIEnv *, jclass, jlong); 129 | 130 | /* 131 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 132 | * Method: setCropHeight 133 | * Signature: (JI)V 134 | */ 135 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_setCropHeight 136 | (JNIEnv *, jclass, jlong, jint); 137 | 138 | /* 139 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 140 | * Method: getUseScaling 141 | * Signature: (J)Z 142 | */ 143 | JNIEXPORT jboolean JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_getUseScaling 144 | (JNIEnv *, jclass, jlong); 145 | 146 | /* 147 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 148 | * Method: getScaledWidth 149 | * Signature: (J)I 150 | */ 151 | JNIEXPORT jint JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_getScaledWidth 152 | (JNIEnv *, jclass, jlong); 153 | 154 | /* 155 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 156 | * Method: setScaledWidth 157 | * Signature: (JI)V 158 | */ 159 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_setScaledWidth 160 | (JNIEnv *, jclass, jlong, jint); 161 | 162 | /* 163 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 164 | * Method: setUseScaling 165 | * Signature: (JZ)V 166 | */ 167 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_setUseScaling 168 | (JNIEnv *, jclass, jlong, jboolean); 169 | 170 | /* 171 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 172 | * Method: getScaledHeight 173 | * Signature: (J)I 174 | */ 175 | JNIEXPORT jint JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_getScaledHeight 176 | (JNIEnv *, jclass, jlong); 177 | 178 | /* 179 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 180 | * Method: setScaledHeight 181 | * Signature: (JI)V 182 | */ 183 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_setScaledHeight 184 | (JNIEnv *, jclass, jlong, jint); 185 | 186 | /* 187 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 188 | * Method: getUseThreads 189 | * Signature: (J)Z 190 | */ 191 | JNIEXPORT jboolean JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_getUseThreads 192 | (JNIEnv *, jclass, jlong); 193 | 194 | /* 195 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 196 | * Method: setUseThreads 197 | * Signature: (JZ)V 198 | */ 199 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_setUseThreads 200 | (JNIEnv *, jclass, jlong, jboolean); 201 | 202 | /* 203 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 204 | * Method: getDitheringStrength 205 | * Signature: (J)I 206 | */ 207 | JNIEXPORT jint JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_getDitheringStrength 208 | (JNIEnv *, jclass, jlong); 209 | 210 | /* 211 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 212 | * Method: setDitheringStrength 213 | * Signature: (JI)V 214 | */ 215 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_setDitheringStrength 216 | (JNIEnv *, jclass, jlong, jint); 217 | 218 | /* 219 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 220 | * Method: getFlip 221 | * Signature: (J)Z 222 | */ 223 | JNIEXPORT jboolean JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_getFlip 224 | (JNIEnv *, jclass, jlong); 225 | 226 | /* 227 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 228 | * Method: setFlip 229 | * Signature: (JZ)V 230 | */ 231 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_setFlip 232 | (JNIEnv *, jclass, jlong, jboolean); 233 | 234 | /* 235 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 236 | * Method: getAlphaDitheringStrength 237 | * Signature: (J)I 238 | */ 239 | JNIEXPORT jint JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_getAlphaDitheringStrength 240 | (JNIEnv *, jclass, jlong); 241 | 242 | /* 243 | * Class: com_luciad_imageio_webp_WebPDecoderOptions 244 | * Method: setAlphaDitheringStrength 245 | * Signature: (JI)V 246 | */ 247 | JNIEXPORT void JNICALL Java_com_luciad_imageio_webp_WebPDecoderOptions_setAlphaDitheringStrength 248 | (JNIEnv *, jclass, jlong, jint); 249 | 250 | #ifdef __cplusplus 251 | } 252 | #endif 253 | #endif 254 | -------------------------------------------------------------------------------- /libwebp-jni/src/main/c/jni/darwin/jni_md.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | #ifndef _JAVASOFT_JNI_MD_H_ 27 | #define _JAVASOFT_JNI_MD_H_ 28 | 29 | #define JNIEXPORT __attribute__((visibility("default"))) 30 | #define JNIIMPORT __attribute__((visibility("default"))) 31 | #define JNICALL 32 | 33 | typedef int jint; 34 | #ifdef _LP64 /* 64-bit */ 35 | typedef long jlong; 36 | #else 37 | typedef long long jlong; 38 | #endif 39 | 40 | typedef signed char jbyte; 41 | 42 | #endif /* !_JAVASOFT_JNI_MD_H_ */ 43 | -------------------------------------------------------------------------------- /libwebp-jni/src/main/c/jni/unix/jni_md.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | #ifndef _JAVASOFT_JNI_MD_H_ 27 | #define _JAVASOFT_JNI_MD_H_ 28 | 29 | #ifndef __has_attribute 30 | #define __has_attribute(x) 0 31 | #endif 32 | #if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) 33 | #ifdef ARM 34 | #define JNIEXPORT __attribute__((externally_visible,visibility("default"))) 35 | #define JNIIMPORT __attribute__((externally_visible,visibility("default"))) 36 | #else 37 | #define JNIEXPORT __attribute__((visibility("default"))) 38 | #define JNIIMPORT __attribute__((visibility("default"))) 39 | #endif 40 | #else 41 | #define JNIEXPORT 42 | #define JNIIMPORT 43 | #endif 44 | 45 | #define JNICALL 46 | 47 | typedef int jint; 48 | #ifdef _LP64 49 | typedef long jlong; 50 | #else 51 | typedef long long jlong; 52 | #endif 53 | 54 | typedef signed char jbyte; 55 | 56 | #endif /* !_JAVASOFT_JNI_MD_H_ */ 57 | -------------------------------------------------------------------------------- /libwebp-jni/src/main/c/jni/windows/jni_md.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | #ifndef _JAVASOFT_JNI_MD_H_ 27 | #define _JAVASOFT_JNI_MD_H_ 28 | 29 | #define JNIEXPORT __declspec(dllexport) 30 | #define JNIIMPORT __declspec(dllimport) 31 | #define JNICALL __stdcall 32 | 33 | // 'long' is always 32 bit on windows so this matches what jdk expects 34 | typedef long jint; 35 | typedef __int64 jlong; 36 | typedef signed char jbyte; 37 | 38 | #endif /* !_JAVASOFT_JNI_MD_H_ */ 39 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "forkProcessing": "enabled", 4 | "assignees": [ 5 | "mateuszkwiecinski" 6 | ], 7 | "extends": [ 8 | "config:recommended" 9 | ], 10 | "packageRules": [ 11 | { 12 | "matchUpdateTypes": [ 13 | "minor", 14 | "patch", 15 | "pin", 16 | "digest" 17 | ], 18 | "automerge": true 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | import org.gradle.api.initialization.resolve.RepositoriesMode 2 | 3 | pluginManagement { 4 | repositories { // https://github.com/gradle/gradle/issues/20866 5 | gradlePluginPortal() 6 | mavenCentral() 7 | google() 8 | } 9 | } 10 | 11 | plugins { 12 | id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" 13 | id("com.gradle.develocity") version "4.0.2" 14 | } 15 | 16 | develocity { 17 | buildScan { 18 | termsOfUseUrl = "https://gradle.com/terms-of-service" 19 | termsOfUseAgree = "yes" 20 | 21 | uploadInBackground = System.getenv("CI") == null 22 | publishing { onlyIf { false } } 23 | } 24 | } 25 | 26 | dependencyResolutionManagement { 27 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 28 | repositories { 29 | google() 30 | mavenCentral() 31 | } 32 | } 33 | 34 | rootProject.name = "com.github.usefulness" 35 | 36 | includeBuild("gradle/plugins") 37 | include("webp-imageio") 38 | -------------------------------------------------------------------------------- /testing/build.gradle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/testing/build.gradle -------------------------------------------------------------------------------- /testing/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/testing/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /testing/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /testing/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | # This is normally unused 84 | # shellcheck disable=SC2034 85 | APP_BASE_NAME=${0##*/} 86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit 88 | 89 | # Use the maximum available, or set MAX_FD != -1 to use that value. 90 | MAX_FD=maximum 91 | 92 | warn () { 93 | echo "$*" 94 | } >&2 95 | 96 | die () { 97 | echo 98 | echo "$*" 99 | echo 100 | exit 1 101 | } >&2 102 | 103 | # OS specific support (must be 'true' or 'false'). 104 | cygwin=false 105 | msys=false 106 | darwin=false 107 | nonstop=false 108 | case "$( uname )" in #( 109 | CYGWIN* ) cygwin=true ;; #( 110 | Darwin* ) darwin=true ;; #( 111 | MSYS* | MINGW* ) msys=true ;; #( 112 | NONSTOP* ) nonstop=true ;; 113 | esac 114 | 115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 116 | 117 | 118 | # Determine the Java command to use to start the JVM. 119 | if [ -n "$JAVA_HOME" ] ; then 120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 121 | # IBM's JDK on AIX uses strange locations for the executables 122 | JAVACMD=$JAVA_HOME/jre/sh/java 123 | else 124 | JAVACMD=$JAVA_HOME/bin/java 125 | fi 126 | if [ ! -x "$JAVACMD" ] ; then 127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 128 | 129 | Please set the JAVA_HOME variable in your environment to match the 130 | location of your Java installation." 131 | fi 132 | else 133 | JAVACMD=java 134 | if ! command -v java >/dev/null 2>&1 135 | then 136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | fi 142 | 143 | # Increase the maximum file descriptors if we can. 144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 145 | case $MAX_FD in #( 146 | max*) 147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 148 | # shellcheck disable=SC2039,SC3045 149 | MAX_FD=$( ulimit -H -n ) || 150 | warn "Could not query maximum file descriptor limit" 151 | esac 152 | case $MAX_FD in #( 153 | '' | soft) :;; #( 154 | *) 155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 156 | # shellcheck disable=SC2039,SC3045 157 | ulimit -n "$MAX_FD" || 158 | warn "Could not set maximum file descriptor limit to $MAX_FD" 159 | esac 160 | fi 161 | 162 | # Collect all arguments for the java command, stacking in reverse order: 163 | # * args from the command line 164 | # * the main class name 165 | # * -classpath 166 | # * -D...appname settings 167 | # * --module-path (only if needed) 168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 169 | 170 | # For Cygwin or MSYS, switch paths to Windows format before running java 171 | if "$cygwin" || "$msys" ; then 172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 174 | 175 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 176 | 177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 178 | for arg do 179 | if 180 | case $arg in #( 181 | -*) false ;; # don't mess with options #( 182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 183 | [ -e "$t" ] ;; #( 184 | *) false ;; 185 | esac 186 | then 187 | arg=$( cygpath --path --ignore --mixed "$arg" ) 188 | fi 189 | # Roll the args list around exactly as many times as the number of 190 | # args, so each arg winds up back in the position where it started, but 191 | # possibly modified. 192 | # 193 | # NB: a `for` loop captures its iteration list before it begins, so 194 | # changing the positional parameters here affects neither the number of 195 | # iterations, nor the values presented in `arg`. 196 | shift # remove old arg 197 | set -- "$@" "$arg" # push replacement arg 198 | done 199 | fi 200 | 201 | 202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 204 | 205 | # Collect all arguments for the java command: 206 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, 207 | # and any embedded shellness will be escaped. 208 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be 209 | # treated as '${Hostname}' itself on the command line. 210 | 211 | set -- \ 212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 213 | -classpath "$CLASSPATH" \ 214 | org.gradle.wrapper.GradleWrapperMain \ 215 | "$@" 216 | 217 | # Stop when "xargs" is not available. 218 | if ! command -v xargs >/dev/null 2>&1 219 | then 220 | die "xargs is not available" 221 | fi 222 | 223 | # Use "xargs" to parse quoted args. 224 | # 225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 226 | # 227 | # In Bash we could simply go: 228 | # 229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 230 | # set -- "${ARGS[@]}" "$@" 231 | # 232 | # but POSIX shell has neither arrays nor command substitution, so instead we 233 | # post-process each arg (as a line of input to sed) to backslash-escape any 234 | # character that might be a shell metacharacter, then use eval to reverse 235 | # that process (while maintaining the separation between arguments), and wrap 236 | # the whole thing up as a single "set" statement. 237 | # 238 | # This will of course break if any of these variables contains a newline or 239 | # an unmatched quote. 240 | # 241 | 242 | eval "set -- $( 243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 244 | xargs -n1 | 245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 246 | tr '\n' ' ' 247 | )" '"$@"' 248 | 249 | exec "$JAVACMD" "$@" 250 | -------------------------------------------------------------------------------- /testing/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /testing/proguard/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.starter.library.kotlin) 3 | id "application" 4 | alias(libs.plugins.johnrengelman.shadow) 5 | } 6 | 7 | application { 8 | mainClass.set("com.webp.imageio.testing.Main") 9 | } 10 | 11 | configurations { 12 | r8 13 | } 14 | 15 | def r8File = layout.buildDirectory.file("libs/${project.name}-r8.jar").get().asFile 16 | def rulesFile = project.file("rules.pro") 17 | def r8JarProvider = tasks.register('r8Jar', JavaExec) { task -> 18 | task.javaLauncher.set(javaToolchains.launcherFor { spec -> 19 | spec.languageVersion.set(JavaLanguageVersion.of(JavaVersion.VERSION_11.majorVersion)) 20 | }) 21 | def fatJar = shadowJar 22 | def fatJarFile = fatJar.archiveFile 23 | task.dependsOn(fatJar) 24 | task.inputs.file(fatJarFile) 25 | task.inputs.file(rulesFile) 26 | task.outputs.file(r8File) 27 | 28 | task.classpath(configurations.r8) 29 | task.mainClass.set('com.android.tools.r8.R8') 30 | task.args = [ 31 | '--release', 32 | '--classfile', 33 | '--output', r8File.toString(), 34 | '--pg-conf', rulesFile.path, 35 | '--lib', providers.systemProperty('java.home').get(), 36 | fatJarFile.get().toString(), 37 | ] 38 | } 39 | artifacts { 40 | archives file: r8File, name: 'binary', type: 'jar', builtBy: r8JarProvider, classifier: 'diffuse' 41 | } 42 | 43 | tasks.named("shadowJar") { 44 | exclude '**/*.kotlin_metadata' 45 | exclude '**/*.kotlin_module' 46 | exclude '**/*.kotlin_builtins' 47 | exclude '**/module-info.class' 48 | exclude 'META-INF/maven/**' 49 | exclude 'META-INF/*.version' 50 | exclude '**/*.proto' 51 | exclude '**/*.dex' 52 | exclude 'LICENSE' 53 | exclude 'NOTICE' 54 | exclude 'r8-version.properties' 55 | exclude 'migrateToAndroidx/*' 56 | exclude 'DebugProbesKt.bin' 57 | } 58 | 59 | dependencies { 60 | r8(libs.r8.core) 61 | runtimeOnly("com.github.usefulness:webp-imageio") 62 | } 63 | -------------------------------------------------------------------------------- /testing/proguard/rules.pro: -------------------------------------------------------------------------------- 1 | -dontobfuscate 2 | -keepattributes SourceFile, LineNumberTable 3 | 4 | -allowaccessmodification 5 | 6 | -keep class com.webp.imageio.testing.Main { 7 | public static void main(java.lang.String[]); 8 | } 9 | -------------------------------------------------------------------------------- /testing/proguard/src/main/kotlin/com/webp/imageio/testing/Main.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("Main") 2 | 3 | package com.webp.imageio.testing 4 | 5 | import javax.imageio.ImageIO 6 | 7 | fun main() { 8 | val input = getResourceStream("lossless.webp") 9 | val image = ImageIO.read(input) 10 | 11 | if(image?.width == 400 && image.height == 301) { 12 | println("All good 👍") 13 | } else { 14 | error("The image didn't load correctly. width=${image?.width}, height=${image?.height}") 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /testing/proguard/src/main/kotlin/com/webp/imageio/testing/ResourcesLoader.kt: -------------------------------------------------------------------------------- 1 | package com.webp.imageio.testing 2 | 3 | private object ResourcesLoader 4 | 5 | internal fun getResourceStream(resource: String) = checkNotNull(ResourcesLoader::class.java.classLoader.getResourceAsStream(resource)) { 6 | "Could not load resource $resource" 7 | } 8 | -------------------------------------------------------------------------------- /testing/proguard/src/main/resources/lossless.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/testing/proguard/src/main/resources/lossless.webp -------------------------------------------------------------------------------- /testing/settings.gradle: -------------------------------------------------------------------------------- 1 | import org.gradle.api.initialization.resolve.RepositoriesMode 2 | 3 | pluginManagement { 4 | repositories { // https://github.com/gradle/gradle/issues/20866 5 | gradlePluginPortal() 6 | mavenCentral() 7 | google() 8 | } 9 | } 10 | 11 | 12 | plugins { 13 | id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" 14 | } 15 | 16 | dependencyResolutionManagement { 17 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 18 | repositories { 19 | google() 20 | mavenCentral() 21 | } 22 | versionCatalogs { 23 | create("libs") { 24 | from(files("../gradle/libs.versions.toml")) 25 | } 26 | } 27 | } 28 | 29 | rootProject.name = "com.github.usefulness.testing" 30 | 31 | include(":proguard") 32 | includeBuild("..") 33 | -------------------------------------------------------------------------------- /webp-imageio/api/webp-imageio.api: -------------------------------------------------------------------------------- 1 | public final class com/luciad/imageio/webp/CompressionType : java/lang/Enum { 2 | public static final field Lossless Lcom/luciad/imageio/webp/CompressionType; 3 | public static final field Lossy Lcom/luciad/imageio/webp/CompressionType; 4 | public static fun getEntries ()Lkotlin/enums/EnumEntries; 5 | public static fun valueOf (Ljava/lang/String;)Lcom/luciad/imageio/webp/CompressionType; 6 | public static fun values ()[Lcom/luciad/imageio/webp/CompressionType; 7 | } 8 | 9 | public class com/luciad/imageio/webp/WebPImageReaderSpi : javax/imageio/spi/ImageReaderSpi { 10 | public fun ()V 11 | public fun canDecodeInput (Ljava/lang/Object;)Z 12 | public fun createReaderInstance (Ljava/lang/Object;)Ljavax/imageio/ImageReader; 13 | public fun getDescription (Ljava/util/Locale;)Ljava/lang/String; 14 | } 15 | 16 | public class com/luciad/imageio/webp/WebPImageWriterSpi : javax/imageio/spi/ImageWriterSpi { 17 | public fun ()V 18 | public fun canEncodeImage (Ljavax/imageio/ImageTypeSpecifier;)Z 19 | public fun createWriterInstance (Ljava/lang/Object;)Ljavax/imageio/ImageWriter; 20 | public fun getDescription (Ljava/util/Locale;)Ljava/lang/String; 21 | } 22 | 23 | public final class com/luciad/imageio/webp/WebPReadParam : javax/imageio/ImageReadParam { 24 | public fun ()V 25 | public final fun getAlphaDitheringStrength ()I 26 | public final fun getBypassFiltering ()Z 27 | public final fun getCropHeight ()I 28 | public final fun getCropLeft ()I 29 | public final fun getCropTop ()I 30 | public final fun getCropWidth ()I 31 | public final fun getDitheringStrength ()I 32 | public final fun getFlipVertically ()Z 33 | public final fun getNoFancyUpsampling ()Z 34 | public final fun getScaledHeight ()I 35 | public final fun getScaledWidth ()I 36 | public final fun getUseCropping ()Z 37 | public final fun getUseScaling ()Z 38 | public final fun getUseThreads ()Z 39 | public final fun setAlphaDitheringStrength (I)V 40 | public final fun setBypassFiltering (Z)V 41 | public final fun setCropHeight (I)V 42 | public final fun setCropLeft (I)V 43 | public final fun setCropTop (I)V 44 | public final fun setCropWidth (I)V 45 | public final fun setDitheringStrength (I)V 46 | public final fun setFlipVertically (Z)V 47 | public final fun setNoFancyUpsampling (Z)V 48 | public final fun setScaledHeight (I)V 49 | public final fun setScaledWidth (I)V 50 | public final fun setUseCropping (Z)V 51 | public final fun setUseScaling (Z)V 52 | public final fun setUseThreads (Z)V 53 | } 54 | 55 | public final class com/luciad/imageio/webp/WebPWriteParam : javax/imageio/ImageWriteParam { 56 | public static final field Companion Lcom/luciad/imageio/webp/WebPWriteParam$Companion; 57 | public static final field LOSSLESS_COMPRESSION I 58 | public static final field LOSSY_COMPRESSION I 59 | public static final field PREPROCESSING_FILTER_NONE I 60 | public static final field PREPROCESSING_FILTER_PSEUDO_RANDOM_DITHERING I 61 | public static final field PREPROCESSING_FILTER_SEGMENT_SMOOTH I 62 | public fun (Ljava/util/Locale;)V 63 | public final fun getAlphaCompressionAlgorithm ()I 64 | public final fun getAlphaFiltering ()I 65 | public final fun getAlphaQuality ()I 66 | public final fun getAutoAdjustFilterStrength ()Z 67 | public fun getCompressionQuality ()F 68 | public final fun getCompressionType ()Lcom/luciad/imageio/webp/CompressionType; 69 | public final fun getEmulateJpegSize ()Z 70 | public final fun getEntropyAnalysisPassCount ()I 71 | public final fun getExact ()Z 72 | public final fun getFilterSharpness ()I 73 | public final fun getFilterStrength ()I 74 | public final fun getFilterType ()I 75 | public final fun getLowMemory ()Z 76 | public final fun getMethod ()I 77 | public final fun getNearLossless ()I 78 | public final fun getPartitionLimit ()I 79 | public final fun getPartitions ()I 80 | public final fun getPreprocessing ()I 81 | public final fun getQMax ()I 82 | public final fun getQMin ()I 83 | public final fun getSegments ()I 84 | public final fun getShowCompressed ()Z 85 | public final fun getSnsStrength ()I 86 | public final fun getTargetPSNR ()F 87 | public final fun getTargetSize ()I 88 | public final fun getThreadLevel ()I 89 | public final fun getUseDeltaPalette ()Z 90 | public final fun getUseSharpYUV ()Z 91 | public final fun setAlphaCompressionAlgorithm (I)V 92 | public final fun setAlphaFiltering (I)V 93 | public final fun setAlphaQuality (I)V 94 | public final fun setAutoAdjustFilterStrength (Z)V 95 | public fun setCompressionQuality (F)V 96 | public final fun setCompressionType (Lcom/luciad/imageio/webp/CompressionType;)V 97 | public fun setCompressionType (Ljava/lang/String;)V 98 | public final fun setEmulateJpegSize (Z)V 99 | public final fun setEntropyAnalysisPassCount (I)V 100 | public final fun setExact (Z)V 101 | public final fun setFilterSharpness (I)V 102 | public final fun setFilterStrength (I)V 103 | public final fun setFilterType (I)V 104 | public final fun setLowMemory (Z)V 105 | public final fun setMethod (I)V 106 | public final fun setNearLossless (I)V 107 | public final fun setPartitionLimit (I)V 108 | public final fun setPartitions (I)V 109 | public final fun setPreprocessing (I)V 110 | public final fun setQMax (I)V 111 | public final fun setQMin (I)V 112 | public final fun setSegments (I)V 113 | public final fun setShowCompressed (Z)V 114 | public final fun setSnsStrength (I)V 115 | public final fun setTargetPSNR (F)V 116 | public final fun setTargetSize (I)V 117 | public final fun setThreadLevel (I)V 118 | public final fun setUseDeltaPalette (Z)V 119 | public final fun setUseSharpYUV (Z)V 120 | public fun unsetCompression ()V 121 | } 122 | 123 | public final class com/luciad/imageio/webp/WebPWriteParam$Companion { 124 | } 125 | 126 | -------------------------------------------------------------------------------- /webp-imageio/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.starter.library.kotlin) 3 | id("com.starter.publishing") 4 | alias(libs.plugins.kotlinx.binarycompatibility) 5 | } 6 | 7 | tasks.withType(Test).configureEach { 8 | useJUnitPlatform() 9 | } 10 | 11 | tasks.withType(JavaCompile).configureEach { 12 | options.headerOutputDirectory.set(rootProject.file("libwebp-jni/src/main/c")) 13 | } 14 | tasks.withType(Javadoc).configureEach { 15 | failOnError = false 16 | options { 17 | addStringOption("Xdoclint:none", "-quiet") 18 | } 19 | } 20 | kotlin { 21 | jvmToolchain(21) 22 | explicitApi() 23 | } 24 | 25 | tasks.register("generateVersionProperties", WriteProperties) { WriteProperties props -> 26 | props.destinationFile = new File(sourceSets.main.output.resourcesDir, "webp-imageio.properties") 27 | props.property("webp_imageio_version", version) 28 | } 29 | 30 | [11, 17].forEach { majorVersion -> 31 | def jdkTest = tasks.register("testJdk$majorVersion", Test) { 32 | javaLauncher = javaToolchains.launcherFor { 33 | languageVersion = JavaLanguageVersion.of(majorVersion) 34 | } 35 | 36 | description = "Runs the test suite on JDK $majorVersion" 37 | group = LifecycleBasePlugin.VERIFICATION_GROUP 38 | 39 | // Copy inputs from normal Test task. 40 | def testTask = tasks.getByName("test") 41 | classpath = testTask.classpath 42 | testClassesDirs = testTask.testClassesDirs 43 | } 44 | tasks.named("check").configure { dependsOn(jdkTest) } 45 | } 46 | 47 | tasks.named("processResources") { 48 | dependsOn("generateVersionProperties") 49 | } 50 | 51 | dependencies { 52 | testImplementation(libs.assertj.core) 53 | testRuntimeOnly(libs.junit.jupiter.engine) 54 | testRuntimeOnly(libs.junit.jupiter.platform) 55 | testImplementation(libs.junit.jupiter.api) 56 | } 57 | -------------------------------------------------------------------------------- /webp-imageio/src/main/java/com/luciad/imageio/webp/WebP.java: -------------------------------------------------------------------------------- 1 | package com.luciad.imageio.webp; 2 | 3 | class WebP { 4 | 5 | static native int[] decode(long aDecoderOptionsPointer, byte[] aData, int aOffset, int aLength, int[] aFlags, boolean aBigEndian); 6 | 7 | static native int getInfo(byte[] aData, int aOffset, int aLength, int[] aOut); 8 | 9 | static native byte[] encodeRGBA(long aConfig, byte[] aRgbaData, int aWidth, int aHeight, int aStride); 10 | 11 | static native byte[] encodeRGB(long aConfig, byte[] aRgbaData, int aWidth, int aHeight, int aStride); 12 | } 13 | -------------------------------------------------------------------------------- /webp-imageio/src/main/java/com/luciad/imageio/webp/WebPDecoderOptions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Luciad (http://www.luciad.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.luciad.imageio.webp; 17 | 18 | 19 | final class WebPDecoderOptions implements Runnable { 20 | 21 | long fPointer; 22 | 23 | public WebPDecoderOptions() { 24 | fPointer = createDecoderOptions(); 25 | if (fPointer == 0) { 26 | throw new OutOfMemoryError(); 27 | } 28 | 29 | WebPWrapper.cleaner.register(this, this); 30 | } 31 | 32 | @Override 33 | public void run() { 34 | deleteDecoderOptions(fPointer); 35 | fPointer = 0L; 36 | } 37 | 38 | public boolean getBypassFiltering() { 39 | return getBypassFiltering(fPointer); 40 | } 41 | 42 | public void setBypassFiltering(boolean aBypassFiltering) { 43 | setBypassFiltering(fPointer, aBypassFiltering); 44 | } 45 | 46 | public boolean getNoFancyUpsampling() { 47 | return getNoFancyUpsampling(fPointer); 48 | } 49 | 50 | 51 | public void setNoFancyUpsampling(boolean aFancyUpsampling) { 52 | setNoFancyUpsampling(fPointer, aFancyUpsampling); 53 | } 54 | 55 | public boolean getUseCropping() { 56 | return getUseCropping(fPointer); 57 | } 58 | 59 | public void setUseCropping(boolean aUseCropping) { 60 | setUseCropping(fPointer, aUseCropping); 61 | } 62 | 63 | public int getCropLeft() { 64 | return getCropLeft(fPointer); 65 | } 66 | 67 | public void setCropLeft(int aCropLeft) { 68 | setCropLeft(fPointer, aCropLeft); 69 | } 70 | 71 | public int getCropTop() { 72 | return getCropTop(fPointer); 73 | } 74 | 75 | public void setCropTop(int aCropTop) { 76 | setCropTop(fPointer, aCropTop); 77 | } 78 | 79 | public int getCropWidth() { 80 | return getCropWidth(fPointer); 81 | } 82 | 83 | public void setCropWidth(int aCropWidth) { 84 | setCropWidth(fPointer, aCropWidth); 85 | } 86 | 87 | public int getCropHeight() { 88 | return getCropHeight(fPointer); 89 | } 90 | 91 | public void setCropHeight(int aCropHeight) { 92 | setCropHeight(fPointer, aCropHeight); 93 | } 94 | 95 | public boolean getUseScaling() { 96 | return getUseScaling(fPointer); 97 | } 98 | 99 | public void setUseScaling(boolean aUseScaling) { 100 | setUseScaling(fPointer, aUseScaling); 101 | } 102 | 103 | public int getScaledWidth() { 104 | return getScaledWidth(fPointer); 105 | } 106 | 107 | public void setScaledWidth(int aScaledWidth) { 108 | setScaledWidth(fPointer, aScaledWidth); 109 | } 110 | 111 | public int getScaledHeight() { 112 | return getScaledHeight(fPointer); 113 | } 114 | 115 | public void setScaledHeight(int aScaledHeight) { 116 | setScaledHeight(fPointer, aScaledHeight); 117 | } 118 | 119 | public boolean getUseThreads() { 120 | return getUseThreads(fPointer); 121 | } 122 | 123 | public void setUseThreads(boolean aUseThreads) { 124 | setUseThreads(fPointer, aUseThreads); 125 | } 126 | 127 | public int getDitheringStrength() { 128 | return getDitheringStrength(fPointer); 129 | } 130 | 131 | public void setDitheringStrength(int aDitheringStrength) { 132 | setDitheringStrength(fPointer, aDitheringStrength); 133 | } 134 | 135 | public boolean getFlip() { 136 | return getFlip(fPointer); 137 | } 138 | 139 | public void setFlip(boolean aFlip) { 140 | setFlip(fPointer, aFlip); 141 | } 142 | 143 | public int getAlphaDitheringStrength() { 144 | return getAlphaDitheringStrength(fPointer); 145 | } 146 | 147 | public void setAlphaDitheringStrength(int aAlphaDitheringStrength) { 148 | setAlphaDitheringStrength(fPointer, aAlphaDitheringStrength); 149 | } 150 | 151 | 152 | private static native long createDecoderOptions(); 153 | 154 | private static native void deleteDecoderOptions(long aPointer); 155 | 156 | private static native boolean getBypassFiltering(long aPointer); 157 | 158 | private static native void setBypassFiltering(long aPointer, boolean aBypassFiltering); 159 | 160 | private static native boolean getNoFancyUpsampling(long aPointer); 161 | 162 | private static native void setNoFancyUpsampling(long aPointer, boolean aNoFancyUpsampling); 163 | 164 | private static native boolean getUseCropping(long aPointer); 165 | 166 | private static native int getCropLeft(long aPointer); 167 | 168 | private static native void setCropLeft(long aPointer, int aCropLeft); 169 | 170 | private static native int getCropTop(long aPointer); 171 | 172 | private static native void setCropTop(long aPointer, int aCropTop); 173 | 174 | private static native void setUseCropping(long aPointer, boolean aUseCropping); 175 | 176 | private static native int getCropWidth(long aPointer); 177 | 178 | private static native void setCropWidth(long aPointer, int aCropWidth); 179 | 180 | private static native int getCropHeight(long aPointer); 181 | 182 | private static native void setCropHeight(long aPointer, int aCropHeight); 183 | 184 | private static native boolean getUseScaling(long aPointer); 185 | 186 | private static native int getScaledWidth(long aPointer); 187 | 188 | private static native void setScaledWidth(long aPointer, int aScaledWidth); 189 | 190 | private static native void setUseScaling(long aPointer, boolean aUseScaling); 191 | 192 | private static native int getScaledHeight(long aPointer); 193 | 194 | private static native void setScaledHeight(long aPointer, int aScaledHeight); 195 | 196 | private static native boolean getUseThreads(long aPointer); 197 | 198 | private static native void setUseThreads(long aPointer, boolean aUseThreads); 199 | 200 | private static native int getDitheringStrength(long aPointer); 201 | 202 | private static native void setDitheringStrength(long aPointer, int aDitheringStrength); 203 | 204 | private static native boolean getFlip(long aPointer); 205 | 206 | private static native void setFlip(long aPointer, boolean aFlip); 207 | 208 | private static native int getAlphaDitheringStrength(long aPointer); 209 | 210 | private static native void setAlphaDitheringStrength(long aPointer, int aAlphaDitheringStrength); 211 | } 212 | -------------------------------------------------------------------------------- /webp-imageio/src/main/kotlin/com/luciad/imageio/webp/CompressionType.kt: -------------------------------------------------------------------------------- 1 | package com.luciad.imageio.webp 2 | 3 | public enum class CompressionType(internal val imageIoValue: String) { 4 | Lossy("Lossy"), 5 | Lossless("Lossless"), 6 | ; 7 | 8 | internal companion object { 9 | 10 | val imageIoCompressionTypes = entries.map { it.imageIoValue }.toTypedArray() 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /webp-imageio/src/main/kotlin/com/luciad/imageio/webp/WebPImageReaderSpi.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Luciad (http://www.luciad.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.luciad.imageio.webp 17 | 18 | import java.nio.ByteOrder 19 | import java.util.Locale 20 | import javax.imageio.ImageReader 21 | import javax.imageio.spi.ImageReaderSpi 22 | import javax.imageio.stream.ImageInputStream 23 | 24 | public open class WebPImageReaderSpi : 25 | ImageReaderSpi( 26 | "Luciad", 27 | "1.0", 28 | arrayOf("WebP", "webp"), 29 | arrayOf("webp"), 30 | arrayOf("image/webp"), 31 | WebPReader::class.java.name, 32 | arrayOf>(ImageInputStream::class.java), 33 | arrayOf(WebPImageWriterSpi::class.java.name), 34 | false, 35 | null, 36 | null, 37 | null, 38 | null, 39 | false, 40 | null, 41 | null, 42 | null, 43 | null, 44 | ) { 45 | override fun createReaderInstance(extension: Any?): ImageReader = WebPReader(this) 46 | 47 | override fun canDecodeInput(source: Any?): Boolean { 48 | if (source !is ImageInputStream) { 49 | return false 50 | } 51 | val readBytes = ByteArray(4) 52 | val oldByteOrder = source.byteOrder 53 | source.mark() 54 | source.byteOrder = ByteOrder.LITTLE_ENDIAN 55 | try { 56 | source.readFully(readBytes) 57 | if (!readBytes.contentEquals(RIFF)) { 58 | return false 59 | } 60 | val chunkLength = source.readUnsignedInt() 61 | val streamLength = source.length() 62 | if (streamLength != -1L && streamLength != chunkLength + 8) { 63 | return false 64 | } 65 | source.readFully(readBytes) 66 | if (!readBytes.contentEquals(WEBP)) { 67 | return false 68 | } 69 | source.readFully(readBytes) 70 | if (!readBytes.contentEquals(VP8_) && !readBytes.contentEquals(VP8L) && !readBytes.contentEquals(VP8X)) { 71 | return false 72 | } 73 | } finally { 74 | source.byteOrder = oldByteOrder 75 | source.reset() 76 | } 77 | return true 78 | } 79 | 80 | override fun getDescription(locale: Locale?): String = "WebP Reader" 81 | } 82 | 83 | private val RIFF = byteArrayOf('R'.code.toByte(), 'I'.code.toByte(), 'F'.code.toByte(), 'F'.code.toByte()) 84 | private val WEBP = byteArrayOf('W'.code.toByte(), 'E'.code.toByte(), 'B'.code.toByte(), 'P'.code.toByte()) 85 | private val VP8_ = byteArrayOf('V'.code.toByte(), 'P'.code.toByte(), '8'.code.toByte(), ' '.code.toByte()) 86 | private val VP8L = byteArrayOf('V'.code.toByte(), 'P'.code.toByte(), '8'.code.toByte(), 'L'.code.toByte()) 87 | private val VP8X = byteArrayOf('V'.code.toByte(), 'P'.code.toByte(), '8'.code.toByte(), 'X'.code.toByte()) 88 | -------------------------------------------------------------------------------- /webp-imageio/src/main/kotlin/com/luciad/imageio/webp/WebPImageWriterSpi.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 Luciad (http://www.luciad.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.luciad.imageio.webp 17 | 18 | import java.awt.image.ComponentColorModel 19 | import java.awt.image.ComponentSampleModel 20 | import java.awt.image.DataBuffer 21 | import java.awt.image.DirectColorModel 22 | import java.awt.image.SinglePixelPackedSampleModel 23 | import java.util.Locale 24 | import javax.imageio.ImageTypeSpecifier 25 | import javax.imageio.ImageWriter 26 | import javax.imageio.spi.ImageWriterSpi 27 | import javax.imageio.stream.ImageOutputStream 28 | 29 | public open class WebPImageWriterSpi : 30 | ImageWriterSpi( 31 | "Luciad", 32 | "1.0", 33 | arrayOf("WebP", "webp"), 34 | arrayOf("webp"), 35 | arrayOf("image/webp"), 36 | WebPReader::class.java.name, 37 | arrayOf>(ImageOutputStream::class.java), 38 | arrayOf(WebPImageReaderSpi::class.java.name), 39 | false, 40 | null, 41 | null, 42 | null, 43 | null, 44 | false, 45 | null, 46 | null, 47 | null, 48 | null, 49 | ) { 50 | 51 | override fun canEncodeImage(type: ImageTypeSpecifier): Boolean { 52 | val colorModel = type.colorModel 53 | val sampleModel = type.sampleModel 54 | val transferType = sampleModel.transferType 55 | if (colorModel is ComponentColorModel) { 56 | if (sampleModel !is ComponentSampleModel) { 57 | return false 58 | } 59 | if (transferType != DataBuffer.TYPE_BYTE && transferType != DataBuffer.TYPE_INT) { 60 | return false 61 | } 62 | } else if (colorModel is DirectColorModel) { 63 | if (sampleModel !is SinglePixelPackedSampleModel) { 64 | return false 65 | } 66 | if (transferType != DataBuffer.TYPE_INT) { 67 | return false 68 | } 69 | } 70 | val sampleSize = sampleModel.sampleSize 71 | for (i in sampleSize.indices) { 72 | if (sampleSize[i] > 8) { 73 | return false 74 | } 75 | } 76 | return true 77 | } 78 | 79 | override fun createWriterInstance(extension: Any?): ImageWriter = WebPWriter(this) 80 | 81 | override fun getDescription(locale: Locale): String = "WebP Writer" 82 | } 83 | -------------------------------------------------------------------------------- /webp-imageio/src/main/kotlin/com/luciad/imageio/webp/WebPReadParam.kt: -------------------------------------------------------------------------------- 1 | package com.luciad.imageio.webp 2 | 3 | import com.luciad.imageio.webp.WebPWrapper.loadNativeLibrary 4 | import javax.imageio.ImageReadParam 5 | 6 | public class WebPReadParam : ImageReadParam() { 7 | 8 | internal val decoderOptions = WebPDecoderOptions() 9 | 10 | /** 11 | * if true, skip the in-loop filtering 12 | */ 13 | public var bypassFiltering: Boolean by decoderOptions::bypassFiltering 14 | 15 | /** 16 | * if true, use faster pointwise upsampler 17 | */ 18 | public var noFancyUpsampling: Boolean by decoderOptions::noFancyUpsampling 19 | 20 | /** 21 | * if true, cropping is applied _first_ 22 | */ 23 | public var useCropping: Boolean by decoderOptions::useCropping 24 | 25 | /** 26 | * top-left position for cropping. Will be snapped to even values. 27 | */ 28 | public var cropLeft: Int by decoderOptions::cropLeft 29 | 30 | /** 31 | * top-left position for cropping. Will be snapped to even values. 32 | */ 33 | public var cropTop: Int by decoderOptions::cropTop 34 | 35 | /** 36 | * dimension of the cropping area 37 | */ 38 | public var cropWidth: Int by decoderOptions::cropWidth 39 | 40 | /** 41 | * dimension of the cropping area 42 | */ 43 | public var cropHeight: Int by decoderOptions::cropHeight 44 | 45 | /** 46 | * if true, scaling is applied _afterward_ 47 | */ 48 | public var useScaling: Boolean by decoderOptions::useScaling 49 | 50 | /** 51 | * final resolution 52 | */ 53 | public var scaledWidth: Int by decoderOptions::scaledWidth 54 | 55 | /** 56 | * final resolution 57 | */ 58 | public var scaledHeight: Int by decoderOptions::scaledHeight 59 | 60 | /** 61 | * if true, use multi-threaded decoding 62 | */ 63 | public var useThreads: Boolean by decoderOptions::useThreads 64 | 65 | /** 66 | * dithering strength (0=Off, 100=full) 67 | */ 68 | public var ditheringStrength: Int by decoderOptions::ditheringStrength 69 | 70 | /** 71 | * if true, flip output vertically 72 | */ 73 | public var flipVertically: Boolean by decoderOptions::flip 74 | 75 | /** 76 | * alpha dithering strength in [0..100] 77 | */ 78 | public var alphaDitheringStrength: Int by decoderOptions::alphaDitheringStrength 79 | 80 | private companion object { 81 | 82 | init { 83 | loadNativeLibrary() 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /webp-imageio/src/main/kotlin/com/luciad/imageio/webp/WebPWriteParam.kt: -------------------------------------------------------------------------------- 1 | package com.luciad.imageio.webp 2 | 3 | import com.luciad.imageio.webp.WebPWrapper.loadNativeLibrary 4 | import java.util.Locale 5 | import javax.imageio.ImageWriteParam 6 | 7 | public class WebPWriteParam(locale: Locale?) : ImageWriteParam(locale) { 8 | 9 | internal val encoderOptions = WebPEncoderOptions() 10 | private val defaultLossless = encoderOptions.lossless 11 | 12 | init { 13 | canWriteCompressed = true 14 | compressionTypes = CompressionType.imageIoCompressionTypes 15 | compressionMode = MODE_EXPLICIT 16 | (if (defaultLossless) CompressionType.Lossless else CompressionType.Lossy) 17 | .imageIoValue 18 | .let(::setCompressionType) 19 | compressionQuality = encoderOptions.compressionQuality / 100f 20 | } 21 | 22 | public override fun getCompressionQuality(): Float = super.getCompressionQuality() 23 | 24 | /** 25 | * For lossy, 0f gives the smallest size and 1f the largest. 26 | * For lossless, this parameter is the amount of effort put into the compression: 27 | * 0f is the fastest but gives larger files compared to the slowest, but best, 1f. 28 | */ 29 | override fun setCompressionQuality(quality: Float) { 30 | super.setCompressionQuality(quality) 31 | encoderOptions.compressionQuality = quality * 100f 32 | } 33 | 34 | public var compressionType: CompressionType 35 | get() = CompressionType.entries.first { it.imageIoValue == getCompressionType() } 36 | set(value) { 37 | setCompressionType(value.imageIoValue) 38 | } 39 | 40 | override fun setCompressionType(compressionType: String) { 41 | super.setCompressionType(compressionType) 42 | 43 | encoderOptions.lossless = when (CompressionType.entries.firstOrNull { it.imageIoValue == compressionType }) { 44 | CompressionType.Lossless -> true 45 | CompressionType.Lossy -> false 46 | null -> error("unrecognised compression type=$compressionType") 47 | } 48 | } 49 | 50 | override fun unsetCompression() { 51 | super.unsetCompression() 52 | encoderOptions.lossless = defaultLossless 53 | } 54 | 55 | /** 56 | * quality/speed trade-off (0=fast, 6=slower-better) 57 | */ 58 | public var method: Int by encoderOptions::method 59 | 60 | /** 61 | * if non-zero, set the desired target size in bytes. 62 | * Takes precedence over the @[.setCompressionQuality] parameter. 63 | */ 64 | public var targetSize: Int by encoderOptions::targetSize 65 | 66 | /** 67 | * if non-zero, specifies the minimal distortion to try to achieve. 68 | * Takes precedence over [.setTargetSize]. 69 | */ 70 | public var targetPSNR: Float by encoderOptions::targetPSNR 71 | 72 | /** 73 | * maximum number of segments to use 74 | */ 75 | public var segments: Int by encoderOptions::segments 76 | 77 | /** 78 | * Spatial Noise Shaping. 0=off, 100=maximum. 79 | */ 80 | public var snsStrength: Int by encoderOptions::snsStrength 81 | 82 | /** 83 | * range: [0 = off .. 100 = strongest] 84 | */ 85 | public var filterStrength: Int by encoderOptions::filterStrength 86 | 87 | /** 88 | * range: [0 = off .. 7 = least sharp] 89 | */ 90 | public var filterSharpness: Int by encoderOptions::filterSharpness 91 | 92 | /** 93 | * filtering type: 0 = simple, 1 = strong (only used if filter_strength > 0 or autofilter > 0) 94 | */ 95 | public var filterType: Int by encoderOptions::filterType 96 | 97 | /** 98 | * Auto adjust filter's strength 99 | */ 100 | public var autoAdjustFilterStrength: Boolean by encoderOptions::autoAdjustFilterStrength 101 | 102 | /** 103 | * Algorithm for encoding the alpha plane 104 | * (0 = none, 1 = compressed with WebP lossless). Default is 1. 105 | */ 106 | public var alphaCompressionAlgorithm: Int by encoderOptions::alphaCompressionAlgorithm 107 | 108 | /** 109 | * Predictive filtering method for alpha plane. 110 | * 0: none, 1: fast, 2: best. Default if 1. 111 | */ 112 | public var alphaFiltering: Int by encoderOptions::alphaFiltering 113 | 114 | /** 115 | * 0: smallest size, 100: lossless. Default is 100. 116 | */ 117 | public var alphaQuality: Int by encoderOptions::alphaQuality 118 | 119 | /** 120 | * Number of entropy-analysis passes 121 | */ 122 | public var entropyAnalysisPassCount: Int by encoderOptions::entropyAnalysisPassCount 123 | 124 | /** 125 | * if true, export the compressed picture back. In-loop filtering is not applied. 126 | */ 127 | public var showCompressed: Boolean by encoderOptions::showCompressed 128 | 129 | /** 130 | * Preprocessing filter 131 | * 0=none, 1=segment-smooth, 2=pseudo-random dithering 132 | */ 133 | public var preprocessing: Int by encoderOptions::preprocessing 134 | 135 | /** 136 | * log2(number of token partitions) in [0..3]. Default is set to 0 for easier progressive decoding. 137 | */ 138 | public var partitions: Int by encoderOptions::partitions 139 | 140 | /** 141 | * Quality degradation allowed to fit the 512k limit on prediction modes coding 142 | * 0: no degradation, 100: maximum possible degradation 143 | */ 144 | public var partitionLimit: Int by encoderOptions::partitionLimit 145 | 146 | /** 147 | * If true, compression parameters will be remapped to better match the expected output size from 148 | * JPEG compression. Generally, the output size will be similar but the degradation will be lower. 149 | */ 150 | public var emulateJpegSize: Boolean by encoderOptions::emulateJpegSize 151 | 152 | /** 153 | * If non-zero, try and use multi-threaded encoding. 154 | */ 155 | public var threadLevel: Int by encoderOptions::threadLevel 156 | 157 | /** 158 | * If set, reduce memory usage (but increase CPU use). 159 | */ 160 | public var lowMemory: Boolean by encoderOptions::lowMemory 161 | 162 | /** 163 | * Near lossless encoding 164 | * 0 = max loss, 100 = off (default) 165 | */ 166 | public var nearLossless: Int by encoderOptions::nearLossless 167 | 168 | /** 169 | * If non-zero, preserve the exact RGB values under transparent area. 170 | * Otherwise, discard this invisible RGB information for better compression. 171 | * The default value is false. 172 | */ 173 | public var exact: Boolean by encoderOptions::exact 174 | 175 | /** 176 | * reserved for future lossless feature 177 | */ 178 | public var useDeltaPalette: Boolean by encoderOptions::useDeltaPalette 179 | 180 | /** 181 | * if needed, use sharp (and slow) RGB->YUV conversion 182 | */ 183 | public var useSharpYUV: Boolean by encoderOptions::useSharpYUV 184 | 185 | /** 186 | * minimum permissible quality factor 187 | */ 188 | public var qMin: Int by encoderOptions::qMin 189 | 190 | /** 191 | * maximum permissible quality factor 192 | */ 193 | public var qMax: Int by encoderOptions::qMax 194 | 195 | public companion object { 196 | 197 | init { 198 | loadNativeLibrary() 199 | } 200 | 201 | public const val LOSSY_COMPRESSION: Int = 0 202 | public const val LOSSLESS_COMPRESSION: Int = 1 203 | 204 | public const val PREPROCESSING_FILTER_NONE: Int = 0 205 | public const val PREPROCESSING_FILTER_SEGMENT_SMOOTH: Int = 1 206 | public const val PREPROCESSING_FILTER_PSEUDO_RANDOM_DITHERING: Int = 2 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /webp-imageio/src/main/kotlin/com/luciad/imageio/webp/internal/JavaUtils.kt: -------------------------------------------------------------------------------- 1 | package com.luciad.imageio.webp.internal 2 | 3 | import java.io.InputStream 4 | 5 | internal fun findProperty(key: String): String? = System.getProperty(key) 6 | 7 | internal fun runProcess(vararg args: String) = Runtime.getRuntime().exec(args).run { 8 | val exitCode = waitFor() 9 | exitCode to inputStream.use(InputStream::readBytes) 10 | .decodeToString() 11 | .trim() 12 | } 13 | -------------------------------------------------------------------------------- /webp-imageio/src/main/kotlin/com/luciad/imageio/webp/internal/OsInfo.kt: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------------------------------------- 2 | * Copyright 2008 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *--------------------------------------------------------------------------*/ 16 | // -------------------------------------- 17 | // sqlite-jdbc Project 18 | // 19 | // OSInfo.java 20 | // Since: May 20, 2008 21 | // 22 | // $URL$ 23 | // $Author$ 24 | // -------------------------------------- 25 | package com.luciad.imageio.webp.internal 26 | 27 | import java.io.IOException 28 | 29 | internal object OsInfo { 30 | private const val X86 = "x86" 31 | private const val X86_64 = "x86_64" 32 | private const val IA64_32 = "ia64_32" 33 | private const val IA64 = "ia64" 34 | private const val PPC = "ppc" 35 | private const val PPC64 = "ppc64" 36 | 37 | @Suppress("ktlint:standard:value-argument-comment") 38 | private val archMapping = mapOf( 39 | // x86 mappings 40 | X86 to X86, 41 | "i386" to X86, 42 | "i486" to X86, 43 | "i586" to X86, 44 | "i686" to X86, 45 | "pentium" to X86, 46 | 47 | // x86_64 mappings 48 | X86_64 to X86_64, 49 | "amd64" to X86_64, 50 | "em64t" to X86_64, 51 | "universal" to X86_64, // Needed for openjdk to Mac, 52 | 53 | // Itenium 64-bit mappings 54 | IA64 to IA64, 55 | "ia64w" to IA64, 56 | 57 | // Itenium 32-bit mappings, usually an HP-UX construct 58 | IA64_32 to IA64_32, 59 | "ia64n" to IA64_32, 60 | 61 | // PowerPC mappings 62 | PPC to PPC, 63 | "power" to PPC, 64 | "powerpc" to PPC, 65 | "power_pc" to PPC, 66 | "power_rs" to PPC, 67 | 68 | // TODO: PowerPC 64bit mappings 69 | PPC64 to PPC64, 70 | "power64" to PPC64, 71 | "powerpc64" to PPC64, 72 | "power_pc64" to PPC64, 73 | "power_rs64" to PPC64, 74 | "ppc64el" to PPC64, 75 | "ppc64le" to PPC64, 76 | ) 77 | 78 | @JvmStatic 79 | fun main(arg: Array) { 80 | println("osName=$oSName") 81 | println("archName=$archName") 82 | println("hardwareName=$hardwareName") 83 | println("isAlpine=$isAlpine") 84 | println("nativeLibFolderPathForCurrentOS=$nativeLibFolderPathForCurrentOS") 85 | } 86 | 87 | @JvmStatic 88 | val nativeLibFolderPathForCurrentOS 89 | get() = "$oSName/$archName" 90 | 91 | @JvmStatic 92 | val oSName 93 | get() = translateOSNameToFolderName(findProperty("os.name").orEmpty()) 94 | 95 | private val isAndroid 96 | get() = findProperty("java.runtime.name").orEmpty().lowercase().contains("android") 97 | 98 | private val isAlpine: Boolean 99 | get() { 100 | return runCatching { 101 | val (_, osReleaseOutput) = runProcess("cat /etc/os-release | grep ^ID") 102 | 103 | osReleaseOutput.contains("alpine", ignoreCase = true) 104 | } 105 | .getOrDefault(false) 106 | } 107 | 108 | @Suppress("TooGenericExceptionCaught") 109 | private val hardwareName: String 110 | get() = runCatching { runProcess("uname", "-m").second } 111 | .onFailure { System.err.println("Error while running uname -m: ${it.message}") } 112 | .getOrDefault("unknown") 113 | 114 | private fun resolveArmArchType(): String { 115 | if (findProperty("os.name").orEmpty().contains("Linux")) { 116 | val armType = hardwareName 117 | 118 | // armType (uname -m) can be armv5t, armv5te, armv5tej, armv5tejl, armv6, armv7, armv7l, aarch64, i686 119 | @Suppress("ktlint:standard:blank-line-between-when-conditions") 120 | when { 121 | armType.startsWith("armv6") -> return "armv6" // Raspberry PI 122 | armType.startsWith("armv7l") -> return "armv7l" 123 | armType.startsWith("armv7") -> return "armv7" // Generic 124 | armType.startsWith("armv5") -> return "arm" // Use armv5, soft-float ABI 125 | armType == "aarch64" -> return "arm64" // Use arm64 126 | else -> Unit 127 | } 128 | 129 | // Java 1.8 introduces a system property to determine armel or armhf 130 | // http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8005545 131 | val abi = findProperty("sun.arch.abi").orEmpty() 132 | if (abi.startsWith("gnueabihf")) { 133 | return "armv7" 134 | } 135 | 136 | // For java7, we still need to if run some shell commands to determine ABI of JVM 137 | val javaHome = findProperty("java.home").orEmpty() 138 | try { 139 | // determine if first JVM found uses ARM hard-float ABI 140 | val (readelfExitCode, _) = runProcess("which", "readelf") 141 | if (readelfExitCode == 0) { 142 | val cmdArray = arrayOf( 143 | "/bin/sh", 144 | "-c", 145 | "find '$javaHome' -name 'libjvm.so' | head -1 | xargs readelf -A | grep 'Tag_ABI_VFP_args: VFP registers'", 146 | ) 147 | val (abiFinderExitCode, _) = runProcess(*cmdArray) 148 | if (abiFinderExitCode == 0) { 149 | return "armv7" 150 | } 151 | } else { 152 | System.err.println( 153 | "WARNING! readelf not found. Cannot check if running on an armhf system, armel architecture will be presumed.", 154 | ) 155 | } 156 | } catch (_: IOException) { 157 | // ignored: fall back to "arm" arch (soft-float ABI) 158 | } catch (_: InterruptedException) { 159 | } 160 | } 161 | // Use armv5, soft-float ABI 162 | return "arm" 163 | } 164 | 165 | @JvmStatic 166 | val archName: String? 167 | get() { 168 | var osArch = findProperty("os.arch").orEmpty() 169 | // For Android 170 | if (isAndroid) { 171 | return "android-arm" 172 | } 173 | if (osArch.startsWith("arm")) { 174 | osArch = resolveArmArchType() 175 | } else { 176 | val lc = osArch.lowercase() 177 | if (archMapping.containsKey(lc)) { 178 | return archMapping[lc] 179 | } 180 | } 181 | return translateArchNameToFolderName(osArch) 182 | } 183 | 184 | private fun translateOSNameToFolderName(osName: String) = when { 185 | osName.contains("Windows") -> "Windows" 186 | osName.contains("Mac") || osName.contains("Darwin") -> "Mac" 187 | isAlpine -> "Linux-Alpine" 188 | osName.contains("Linux") -> "Linux" 189 | osName.contains("AIX") -> "AIX" 190 | else -> osName.replace("\\W".toRegex(), "") 191 | } 192 | 193 | private fun translateArchNameToFolderName(archName: String) = archName.replace("\\W".toRegex(), "") 194 | } 195 | -------------------------------------------------------------------------------- /webp-imageio/src/main/kotlin/com/luciad/imageio/webp/internal/VP8StatusCode.kt: -------------------------------------------------------------------------------- 1 | package com.luciad.imageio.webp.internal 2 | 3 | internal enum class VP8StatusCode { 4 | Ok, 5 | OutOfMemory, 6 | InvalidParam, 7 | BitstreamError, 8 | UnsupportedFeature, 9 | Suspended, 10 | UserAbort, 11 | NotEnoughData, 12 | ; 13 | 14 | companion object { 15 | 16 | fun getStatusCode(aValue: Int) = entries.getOrNull(aValue) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /webp-imageio/src/main/kotlin/com/luciad/imageio/webp/internal/WebPReader.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("PackageDirectoryMismatch", "InvalidPackageDeclaration") 2 | 3 | /* 4 | * Copyright 2013 Luciad (http://www.luciad.com) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package com.luciad.imageio.webp 20 | 21 | import java.awt.image.BufferedImage 22 | import java.awt.image.DataBufferInt 23 | import java.awt.image.DirectColorModel 24 | import java.awt.image.WritableRaster 25 | import java.io.ByteArrayOutputStream 26 | import java.io.IOException 27 | import java.lang.IndexOutOfBoundsException 28 | import java.util.Hashtable 29 | import javax.imageio.ImageReadParam 30 | import javax.imageio.ImageReader 31 | import javax.imageio.ImageTypeSpecifier 32 | import javax.imageio.metadata.IIOMetadata 33 | import javax.imageio.spi.ImageReaderSpi 34 | import javax.imageio.stream.ImageInputStream 35 | 36 | internal class WebPReader(originatingProvider: ImageReaderSpi) : ImageReader(originatingProvider) { 37 | 38 | private var cachedData: ByteArray? = null 39 | private var cachedHeader: Pair? = null 40 | 41 | override fun setInput(input: Any, seekForwardOnly: Boolean, ignoreMetadata: Boolean) { 42 | super.setInput(input, seekForwardOnly, ignoreMetadata) 43 | cachedData = null 44 | cachedHeader = null 45 | } 46 | 47 | override fun getNumImages(allowSearch: Boolean): Int = 1 48 | 49 | private fun readHeader(): Pair { 50 | cachedHeader?.let { return it } 51 | 52 | val data = readData() 53 | val (width, height) = WebPWrapper.getInfo(data, 0, data.size) 54 | 55 | return width to height 56 | } 57 | 58 | private fun readData(): ByteArray { 59 | cachedData?.let { return it } 60 | 61 | val input = getInput() as ImageInputStream 62 | val length = input.length() 63 | if (length > Int.MAX_VALUE) { 64 | throw IOException("Cannot read image of size $length") 65 | } 66 | if (input.streamPosition != 0L) { 67 | if (isSeekForwardOnly) { 68 | throw IOException() 69 | } else { 70 | input.seek(0) 71 | } 72 | } 73 | val data = if (length > 0) { 74 | ByteArray(length.toInt()).also(input::readFully) 75 | } else { 76 | ByteArrayOutputStream().use { out -> 77 | val buffer = ByteArray(4096) 78 | var bytesRead: Int 79 | while (input.read(buffer).also { bytesRead = it } != -1) { 80 | out.write(buffer, 0, bytesRead) 81 | } 82 | out.toByteArray() 83 | } 84 | } 85 | cachedData = data 86 | 87 | return data 88 | } 89 | 90 | private fun checkIndex(imageIndex: Int) { 91 | if (imageIndex != 0) { 92 | throw IndexOutOfBoundsException("Invalid image index") 93 | } 94 | } 95 | 96 | override fun getWidth(imageIndex: Int): Int { 97 | checkIndex(imageIndex) 98 | val (width, _) = readHeader() 99 | 100 | return width 101 | } 102 | 103 | override fun getHeight(imageIndex: Int): Int { 104 | checkIndex(imageIndex) 105 | val (_, height) = readHeader() 106 | 107 | return height 108 | } 109 | 110 | override fun getStreamMetadata(): IIOMetadata? = null 111 | 112 | override fun getImageMetadata(imageIndex: Int): IIOMetadata? = null 113 | 114 | override fun getImageTypes(imageIndex: Int) = listOf(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_ARGB)) 115 | .iterator() 116 | 117 | override fun getDefaultReadParam() = WebPReadParam() 118 | 119 | override fun read(imageIndex: Int, param: ImageReadParam?): BufferedImage { 120 | checkIndex(imageIndex) 121 | val data = readData() 122 | readHeader() 123 | val readParam = (param as? WebPReadParam) ?: defaultReadParam 124 | val outParams = IntArray(4) 125 | val pixels = WebPWrapper.decode(readParam.decoderOptions, data, 0, data.size, outParams) 126 | val width = outParams[1] 127 | val height = outParams[2] 128 | val alpha = outParams[3] != 0 129 | val colorModel = if (alpha) { 130 | DirectColorModel(32, 0x00ff0000, 0x0000ff00, 0x000000ff, -0x1000000) 131 | } else { 132 | DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000) 133 | } 134 | val sampleModel = colorModel.createCompatibleSampleModel(width, height) 135 | val db = DataBufferInt(pixels, width * height) 136 | val raster = WritableRaster.createWritableRaster(sampleModel, db, null) 137 | 138 | return BufferedImage(colorModel, raster, false, Hashtable()) 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /webp-imageio/src/main/kotlin/com/luciad/imageio/webp/internal/WebPWrapper.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("PackageDirectoryMismatch", "InvalidPackageDeclaration") 2 | 3 | package com.luciad.imageio.webp 4 | 5 | import com.luciad.imageio.webp.internal.VP8StatusCode.Companion.getStatusCode 6 | import com.luciad.imageio.webp.WebP.decode 7 | import com.luciad.imageio.webp.WebP.encodeRGB 8 | import com.luciad.imageio.webp.WebP.encodeRGBA 9 | import com.luciad.imageio.webp.WebP.getInfo 10 | import com.luciad.imageio.webp.internal.NativeLoader.initialize 11 | import com.luciad.imageio.webp.internal.VP8StatusCode 12 | import java.io.IOException 13 | import java.lang.ref.Cleaner 14 | import java.nio.ByteOrder 15 | 16 | internal object WebPWrapper { 17 | 18 | private var NATIVE_LIBRARY_LOADED = false 19 | 20 | @JvmField 21 | val cleaner: Cleaner = Cleaner.create() 22 | 23 | init { 24 | loadNativeLibrary() 25 | } 26 | 27 | @JvmStatic 28 | @Synchronized 29 | fun loadNativeLibrary() { 30 | if (!NATIVE_LIBRARY_LOADED) { 31 | runCatching { initialize() } 32 | .onFailure { it.printStackTrace() } 33 | NATIVE_LIBRARY_LOADED = true 34 | } 35 | } 36 | 37 | fun decode(options: WebPDecoderOptions, data: ByteArray, offset: Int, length: Int, out: IntArray): IntArray { 38 | require(offset + length <= data.size) { "Offset/length exceeds array size" } 39 | 40 | val pixels = decode( 41 | options.fPointer, 42 | data, 43 | offset, 44 | length, 45 | out, 46 | ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN, 47 | ) 48 | when (val status = getStatusCode(out[0])) { 49 | VP8StatusCode.Ok -> return pixels 50 | VP8StatusCode.OutOfMemory -> throw OutOfMemoryError() 51 | else -> throw IOException("Decode returned code $status") 52 | } 53 | } 54 | 55 | fun getInfo(data: ByteArray, offset: Int, length: Int): IntArray { 56 | val out = IntArray(2) 57 | val result = getInfo(data, offset, length, out) 58 | if (result == 0) { 59 | throw IOException("Invalid WebP data") 60 | } 61 | 62 | return out 63 | } 64 | 65 | fun encodeRGBA(options: WebPEncoderOptions, rgbaData: ByteArray, width: Int, height: Int, stride: Int): ByteArray = 66 | encodeRGBA(options.pointer, rgbaData, width, height, stride) 67 | 68 | fun encodeRGB(options: WebPEncoderOptions, rgbaData: ByteArray, width: Int, height: Int, stride: Int): ByteArray = 69 | encodeRGB(options.pointer, rgbaData, width, height, stride) 70 | } 71 | -------------------------------------------------------------------------------- /webp-imageio/src/main/resources/META-INF/proguard/web-imageio.pro: -------------------------------------------------------------------------------- 1 | -keep class com.luciad.imageio.webp.WebP { *; } 2 | -keep class com.luciad.imageio.webp.WebPImageWriterSpi { *; } 3 | -keep class com.luciad.imageio.webp.WebPImageReaderSpi { *; } 4 | -------------------------------------------------------------------------------- /webp-imageio/src/main/resources/META-INF/services/javax.imageio.spi.ImageReaderSpi: -------------------------------------------------------------------------------- 1 | com.luciad.imageio.webp.WebPImageReaderSpi -------------------------------------------------------------------------------- /webp-imageio/src/main/resources/META-INF/services/javax.imageio.spi.ImageWriterSpi: -------------------------------------------------------------------------------- 1 | com.luciad.imageio.webp.WebPImageWriterSpi -------------------------------------------------------------------------------- /webp-imageio/src/main/resources/native/Linux/aarch64/libwebp-imageio.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/main/resources/native/Linux/aarch64/libwebp-imageio.so -------------------------------------------------------------------------------- /webp-imageio/src/main/resources/native/Linux/arm/libwebp-imageio.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/main/resources/native/Linux/arm/libwebp-imageio.so -------------------------------------------------------------------------------- /webp-imageio/src/main/resources/native/Linux/armv6/libwebp-imageio.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/main/resources/native/Linux/armv6/libwebp-imageio.so -------------------------------------------------------------------------------- /webp-imageio/src/main/resources/native/Linux/armv7/libwebp-imageio.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/main/resources/native/Linux/armv7/libwebp-imageio.so -------------------------------------------------------------------------------- /webp-imageio/src/main/resources/native/Linux/ppc64/libwebp-imageio.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/main/resources/native/Linux/ppc64/libwebp-imageio.so -------------------------------------------------------------------------------- /webp-imageio/src/main/resources/native/Linux/x86/libwebp-imageio.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/main/resources/native/Linux/x86/libwebp-imageio.so -------------------------------------------------------------------------------- /webp-imageio/src/main/resources/native/Linux/x86_64/libwebp-imageio.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/main/resources/native/Linux/x86_64/libwebp-imageio.so -------------------------------------------------------------------------------- /webp-imageio/src/main/resources/native/Mac/aarch64/libwebp-imageio.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/main/resources/native/Mac/aarch64/libwebp-imageio.dylib -------------------------------------------------------------------------------- /webp-imageio/src/main/resources/native/Mac/x86_64/libwebp-imageio.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/main/resources/native/Mac/x86_64/libwebp-imageio.dylib -------------------------------------------------------------------------------- /webp-imageio/src/main/resources/native/Windows/x86/webp-imageio.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/main/resources/native/Windows/x86/webp-imageio.dll -------------------------------------------------------------------------------- /webp-imageio/src/main/resources/native/Windows/x86_64/webp-imageio.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/main/resources/native/Windows/x86_64/webp-imageio.dll -------------------------------------------------------------------------------- /webp-imageio/src/test/kotlin/com/luciad/imageio/webp/SimpleTest.kt: -------------------------------------------------------------------------------- 1 | package com.luciad.imageio.webp 2 | 3 | import com.luciad.imageio.webp.utils.readImage 4 | import com.luciad.imageio.webp.utils.readResource 5 | import org.assertj.core.api.Assertions.assertThat 6 | import org.junit.jupiter.api.Test 7 | 8 | class SimpleTest { 9 | 10 | /** 11 | * For some reason this reproduces the issue from https://github.com/usefulness/webp-imageio/issues/111 12 | */ 13 | @Test 14 | fun readLossy() { 15 | val image = readImage(readResource("lossy.webp")) 16 | 17 | assertThat(image.width).isEqualTo(1024) 18 | assertThat(image.height).isEqualTo(752) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /webp-imageio/src/test/kotlin/com/luciad/imageio/webp/WebPImageReaderSpiTest.kt: -------------------------------------------------------------------------------- 1 | package com.luciad.imageio.webp 2 | 3 | import com.luciad.imageio.webp.utils.getImageReader 4 | import com.luciad.imageio.webp.utils.readResource 5 | import org.assertj.core.api.Assertions.assertThat 6 | import org.junit.jupiter.api.Test 7 | import java.io.ByteArrayInputStream 8 | import javax.imageio.stream.MemoryCacheImageInputStream 9 | 10 | class WebPImageReaderSpiTest { 11 | 12 | @Test 13 | fun throwsProperException() { 14 | val result = runCatching { 15 | val resource = readResource("lossy.webp") 16 | MemoryCacheImageInputStream(ByteArrayInputStream(resource)).use { input -> 17 | getImageReader(resource) 18 | .apply { this.input = input } 19 | .read(2, null) 20 | } 21 | } 22 | 23 | assertThat(result.exceptionOrNull()).isInstanceOf(IndexOutOfBoundsException::class.java) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /webp-imageio/src/test/kotlin/com/luciad/imageio/webp/internal/NativeLoaderTest.kt: -------------------------------------------------------------------------------- 1 | package com.luciad.imageio.webp.internal 2 | 3 | import org.assertj.core.api.Assertions.assertThat 4 | import org.junit.jupiter.api.AfterEach 5 | import org.junit.jupiter.api.BeforeEach 6 | import org.junit.jupiter.api.Test 7 | import java.util.logging.Logger 8 | 9 | class NativeLoaderTest { 10 | 11 | private val log = Logger.getLogger(NativeLoaderTest::class.java.name) 12 | 13 | @BeforeEach 14 | fun setUp() { 15 | check(NativeLoader.initialize()) 16 | } 17 | 18 | @AfterEach 19 | fun tearDown() { 20 | NativeLoader.cleanup() 21 | } 22 | 23 | @Test 24 | fun checkVersion() { 25 | log.info("Native version is: ${NativeLoader.version}") 26 | assertThat(NativeLoader.version).isNotEqualTo("unknown") 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /webp-imageio/src/test/kotlin/com/luciad/imageio/webp/internal/OsInfoTest.kt: -------------------------------------------------------------------------------- 1 | package com.luciad.imageio.webp.internal 2 | 3 | import org.assertj.core.api.Assertions.assertThat 4 | import org.junit.jupiter.api.Test 5 | import java.util.logging.Logger 6 | 7 | class OsInfoTest { 8 | 9 | private val log = Logger.getLogger(OsInfoTest::class.java.name) 10 | 11 | @Test 12 | fun smokeTest() { 13 | log.info("Native lib folder path for current OS is: ${OsInfo.nativeLibFolderPathForCurrentOS}") 14 | assertThat(OsInfo.nativeLibFolderPathForCurrentOS).isNotEqualTo("/") 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /webp-imageio/src/test/kotlin/com/luciad/imageio/webp/utils/ResourcesLoader.kt: -------------------------------------------------------------------------------- 1 | package com.luciad.imageio.webp.utils 2 | 3 | import java.io.ByteArrayOutputStream 4 | 5 | private object ResourcesLoader 6 | 7 | internal fun readResource(resource: String) = getResourceStream(resource).use { stream -> 8 | ByteArrayOutputStream().use { out -> 9 | stream.copyTo(out) 10 | out.toByteArray() 11 | } 12 | } 13 | 14 | internal fun getResourceStream(resource: String) = checkNotNull(ResourcesLoader::class.java.classLoader.getResourceAsStream(resource)) { 15 | "Could not load resource $resource" 16 | } 17 | -------------------------------------------------------------------------------- /webp-imageio/src/test/kotlin/com/luciad/imageio/webp/utils/TestUtils.kt: -------------------------------------------------------------------------------- 1 | package com.luciad.imageio.webp.utils 2 | 3 | import com.luciad.imageio.webp.WebPImageReaderSpi 4 | import com.luciad.imageio.webp.WebPImageWriterSpi 5 | import com.luciad.imageio.webp.WebPWriteParam 6 | import java.awt.image.BufferedImage 7 | import java.io.ByteArrayInputStream 8 | import java.io.File 9 | import javax.imageio.IIOImage 10 | import javax.imageio.ImageIO 11 | import javax.imageio.ImageReadParam 12 | import javax.imageio.ImageReader 13 | import javax.imageio.ImageWriter 14 | import javax.imageio.stream.FileImageOutputStream 15 | import javax.imageio.stream.ImageInputStream 16 | import javax.imageio.stream.MemoryCacheImageInputStream 17 | 18 | internal fun Iterator.requireWebpImageReader() = asSequence().single { it.originatingProvider is WebPImageReaderSpi } 19 | internal fun Iterator.requireWebpImageWriter() = asSequence().single { it.originatingProvider is WebPImageWriterSpi } 20 | 21 | internal fun readImage(webp: ByteArray, param: ImageReadParam? = null) = 22 | MemoryCacheImageInputStream(ByteArrayInputStream(webp)).use { input -> 23 | getImageReader(webp) 24 | .apply { this.input = input } 25 | .read(0, param) 26 | } 27 | 28 | internal fun getImageReader(data: ByteArray): ImageReader { 29 | val stream = MemoryCacheImageInputStream(ByteArrayInputStream(data)) 30 | 31 | return ImageIO.getImageReaders(stream).requireWebpImageReader() 32 | } 33 | 34 | internal fun writeWebpImage(input: BufferedImage, target: ImageInputStream, params: WebPWriteParam.() -> Unit = { }) = 35 | ImageIO.getImageWritersByMIMEType("image/webp") 36 | .asSequence() 37 | .single() 38 | .run { 39 | output = target 40 | val updated = (defaultWriteParam as WebPWriteParam).apply(params) 41 | write(null, IIOImage(input, null, null), updated) 42 | } 43 | 44 | internal fun writeWebpImage(input: BufferedImage, target: File, params: WebPWriteParam.() -> Unit = { }) = 45 | FileImageOutputStream(target).use { stream -> 46 | writeWebpImage( 47 | input = input, 48 | target = stream, 49 | params = params, 50 | ) 51 | } 52 | -------------------------------------------------------------------------------- /webp-imageio/src/test/resources/lossless.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/test/resources/lossless.webp -------------------------------------------------------------------------------- /webp-imageio/src/test/resources/lossy.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/test/resources/lossy.webp -------------------------------------------------------------------------------- /webp-imageio/src/test/resources/lossy_alpha.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/test/resources/lossy_alpha.webp -------------------------------------------------------------------------------- /webp-imageio/src/test/resources/non_rgb_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/test/resources/non_rgb_1.jpg -------------------------------------------------------------------------------- /webp-imageio/src/test/resources/non_rgb_2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/test/resources/non_rgb_2.jpeg -------------------------------------------------------------------------------- /webp-imageio/src/test/resources/test4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/test/resources/test4.png -------------------------------------------------------------------------------- /webp-imageio/src/test/resources/test4_default.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/test/resources/test4_default.webp -------------------------------------------------------------------------------- /webp-imageio/src/test/resources/test4_sharp.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usefulness/webp-imageio/238f02be02a8032eca2613bb9f0d648d56207a40/webp-imageio/src/test/resources/test4_sharp.webp --------------------------------------------------------------------------------