├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── .svu.yml ├── DEVELOPING.md ├── LICENSE ├── README.md ├── build.gradle ├── gradle.properties ├── gradle ├── dependencies.gradle ├── mrjar.gradle ├── publish.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── imageio-common ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── github │ │ └── gotson │ │ └── nightmonkeys │ │ └── common │ │ └── imageio │ │ ├── IIOUtil.java │ │ ├── ImageReaderSpiBase.java │ │ ├── ImageWriterSpiBase.java │ │ └── ProviderInfo.java │ └── testFixtures │ └── java │ └── com │ └── github │ └── gotson │ └── nightmonkeys │ └── common │ └── imageio │ ├── ImageReaderAbstractTest.java │ ├── ImageWriterAbstractTest.java │ ├── NoOpImageReaderAbstractTest.java │ └── NoOpImageWriterAbstractTest.java ├── imageio-heif ├── README.md ├── build.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── github │ │ │ └── gotson │ │ │ └── nightmonkeys │ │ │ └── heif │ │ │ └── imageio │ │ │ └── plugins │ │ │ ├── HeifImageReader.java │ │ │ ├── HeifImageReaderSpi.java │ │ │ ├── HeifImageWriter.java │ │ │ ├── HeifImageWriterSpi.java │ │ │ └── HeifProviderInfo.java │ ├── java22 │ │ └── com │ │ │ └── github │ │ │ └── gotson │ │ │ └── nightmonkeys │ │ │ └── heif │ │ │ ├── BasicInfo.java │ │ │ ├── Heif.java │ │ │ ├── HeifEncoder.java │ │ │ ├── HeifException.java │ │ │ ├── imageio │ │ │ └── plugins │ │ │ │ ├── HeifImageReader.java │ │ │ │ ├── HeifImageReaderSpi.java │ │ │ │ ├── HeifImageWriter.java │ │ │ │ ├── HeifImageWriterSpi.java │ │ │ │ ├── HeifLibraryLoader.java │ │ │ │ └── HeifWriteParam.java │ │ │ └── lib │ │ │ ├── HeifError.java │ │ │ ├── enums │ │ │ ├── HeifChannel.java │ │ │ ├── HeifChroma.java │ │ │ ├── HeifColorSpace.java │ │ │ ├── HeifCompressionFormat.java │ │ │ ├── HeifErrorCode.java │ │ │ ├── HeifFiletypeResult.java │ │ │ └── HeifSuberrorCode.java │ │ │ └── panama │ │ │ ├── __darwin_mbstate_t.java │ │ │ ├── __darwin_pthread_attr_t.java │ │ │ ├── __darwin_pthread_cond_t.java │ │ │ ├── __darwin_pthread_condattr_t.java │ │ │ ├── __darwin_pthread_handler_rec.java │ │ │ ├── __darwin_pthread_mutex_t.java │ │ │ ├── __darwin_pthread_mutexattr_t.java │ │ │ ├── __darwin_pthread_once_t.java │ │ │ ├── __darwin_pthread_rwlock_t.java │ │ │ ├── __darwin_pthread_rwlockattr_t.java │ │ │ ├── __mbstate_t.java │ │ │ ├── _opaque_pthread_attr_t.java │ │ │ ├── _opaque_pthread_cond_t.java │ │ │ ├── _opaque_pthread_condattr_t.java │ │ │ ├── _opaque_pthread_mutex_t.java │ │ │ ├── _opaque_pthread_mutexattr_t.java │ │ │ ├── _opaque_pthread_once_t.java │ │ │ ├── _opaque_pthread_rwlock_t.java │ │ │ ├── _opaque_pthread_rwlockattr_t.java │ │ │ ├── _opaque_pthread_t.java │ │ │ ├── heif_color_conversion_options.java │ │ │ ├── heif_color_profile_nclx.java │ │ │ ├── heif_content_light_level.java │ │ │ ├── heif_decoded_mastering_display_colour_volume.java │ │ │ ├── heif_decoding_options.java │ │ │ ├── heif_depth_representation_info.java │ │ │ ├── heif_encoding_options.java │ │ │ ├── heif_error.java │ │ │ ├── heif_h.java │ │ │ ├── heif_init_params.java │ │ │ ├── heif_mastering_display_colour_volume.java │ │ │ ├── heif_plugin_info.java │ │ │ ├── heif_property_user_description.java │ │ │ ├── heif_reader.java │ │ │ └── heif_writer.java │ └── resources │ │ └── META-INF │ │ └── services │ │ ├── javax.imageio.spi.ImageReaderSpi │ │ └── javax.imageio.spi.ImageWriterSpi │ └── test │ ├── java │ └── com │ │ └── github │ │ └── gotson │ │ └── nightmonkeys │ │ └── heif │ │ └── imageio │ │ └── plugins │ │ ├── HeifImageReaderTest.java │ │ └── HeifImageWriterTest.java │ ├── java22 │ └── com │ │ └── github │ │ └── gotson │ │ └── nightmonkeys │ │ └── heif │ │ └── imageio │ │ └── plugins │ │ ├── HeifImageReaderTest.java │ │ └── HeifImageWriterTest.java │ └── resources │ ├── avif │ ├── animation2.avif │ ├── avif-enabled.avif │ ├── kk.avif │ └── monster.avif │ └── heif │ ├── C006.heic │ ├── animation_sea1.heic │ ├── animation_starfield.heic │ ├── autumn_1440x960.heic │ ├── burst_bird.heic │ ├── burst_rally.heic │ ├── collection_random_1440x960.heic │ ├── collection_season_1440x960.heic │ ├── dwsample-heif-640.heif │ └── old_bridge_1440x960.heic ├── imageio-jxl ├── README.md ├── build.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── github │ │ │ └── gotson │ │ │ └── nightmonkeys │ │ │ └── jxl │ │ │ └── imageio │ │ │ └── plugins │ │ │ ├── JxlImageReader.java │ │ │ ├── JxlImageReaderSpi.java │ │ │ └── JxlProviderInfo.java │ ├── java22 │ │ └── com │ │ │ └── github │ │ │ └── gotson │ │ │ └── nightmonkeys │ │ │ └── jxl │ │ │ ├── BasicInfo.java │ │ │ ├── JpegXl.java │ │ │ ├── JxlException.java │ │ │ ├── imageio │ │ │ └── plugins │ │ │ │ ├── JxlImageReader.java │ │ │ │ └── JxlImageReaderSpi.java │ │ │ └── lib │ │ │ ├── enums │ │ │ ├── JxlColorProfileTarget.java │ │ │ ├── JxlDataType.java │ │ │ ├── JxlDecoderStatus.java │ │ │ ├── JxlEndianness.java │ │ │ ├── JxlOrientation.java │ │ │ └── JxlSignature.java │ │ │ └── panama │ │ │ ├── JxlAnimationHeader.java │ │ │ ├── JxlBasicInfo.java │ │ │ ├── JxlColorEncoding.java │ │ │ ├── JxlExtraChannelInfo.java │ │ │ ├── JxlFrameHeader.java │ │ │ ├── JxlHeaderExtensions.java │ │ │ ├── JxlImageOutCallback.java │ │ │ ├── JxlMemoryManager.java │ │ │ ├── JxlMemoryManagerStruct.java │ │ │ ├── JxlParallelRunFunction.java │ │ │ ├── JxlParallelRunInit.java │ │ │ ├── JxlParallelRunner.java │ │ │ ├── JxlPixelFormat.java │ │ │ ├── JxlPreviewHeader.java │ │ │ ├── __darwin_mbstate_t.java │ │ │ ├── __darwin_pthread_attr_t.java │ │ │ ├── __darwin_pthread_cond_t.java │ │ │ ├── __darwin_pthread_condattr_t.java │ │ │ ├── __darwin_pthread_handler_rec.java │ │ │ ├── __darwin_pthread_mutex_t.java │ │ │ ├── __darwin_pthread_mutexattr_t.java │ │ │ ├── __darwin_pthread_once_t.java │ │ │ ├── __darwin_pthread_rwlock_t.java │ │ │ ├── __darwin_pthread_rwlockattr_t.java │ │ │ ├── __mbstate_t.java │ │ │ ├── _opaque_pthread_attr_t.java │ │ │ ├── _opaque_pthread_cond_t.java │ │ │ ├── _opaque_pthread_condattr_t.java │ │ │ ├── _opaque_pthread_mutex_t.java │ │ │ ├── _opaque_pthread_mutexattr_t.java │ │ │ ├── _opaque_pthread_once_t.java │ │ │ ├── _opaque_pthread_rwlock_t.java │ │ │ ├── _opaque_pthread_rwlockattr_t.java │ │ │ ├── _opaque_pthread_t.java │ │ │ ├── decode_h.java │ │ │ ├── jpegxl_alloc_func.java │ │ │ └── jpegxl_free_func.java │ └── resources │ │ └── META-INF │ │ └── services │ │ └── javax.imageio.spi.ImageReaderSpi │ └── test │ ├── java │ └── com │ │ └── github │ │ └── gotson │ │ └── nightmonkeys │ │ └── jxl │ │ └── imageio │ │ └── plugins │ │ └── JpegXlImageReaderTest.java │ ├── java22 │ └── com │ │ └── github │ │ └── gotson │ │ └── nightmonkeys │ │ └── jxl │ │ └── imageio │ │ └── plugins │ │ └── JpegXlImageReaderTest.java │ └── resources │ └── jxl │ ├── animation.jxl │ ├── gray.jxl │ ├── hills.jxl │ └── island.jxl ├── imageio-webp ├── README.md ├── build.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── github │ │ │ └── gotson │ │ │ └── nightmonkeys │ │ │ └── webp │ │ │ └── imageio │ │ │ └── plugins │ │ │ ├── WebpImageReader.java │ │ │ ├── WebpImageReaderSpi.java │ │ │ └── WebpProviderInfo.java │ ├── java22 │ │ └── com │ │ │ └── github │ │ │ └── gotson │ │ │ └── nightmonkeys │ │ │ └── webp │ │ │ ├── BasicInfo.java │ │ │ ├── WebP.java │ │ │ ├── WebpException.java │ │ │ ├── imageio │ │ │ └── plugins │ │ │ │ ├── WebpImageReader.java │ │ │ │ └── WebpImageReaderSpi.java │ │ │ └── lib │ │ │ ├── enums │ │ │ ├── VP8StatusCode.java │ │ │ ├── WebPDemuxState.java │ │ │ ├── WebPFeatureFlags.java │ │ │ └── WebPFormatFeature.java │ │ │ └── panama │ │ │ ├── webp │ │ │ ├── WebPBitstreamFeatures.java │ │ │ ├── WebPDecBuffer.java │ │ │ ├── WebPDecoderConfig.java │ │ │ ├── WebPDecoderOptions.java │ │ │ ├── WebPRGBABuffer.java │ │ │ ├── WebPYUVABuffer.java │ │ │ ├── __darwin_mbstate_t.java │ │ │ ├── __darwin_pthread_attr_t.java │ │ │ ├── __darwin_pthread_cond_t.java │ │ │ ├── __darwin_pthread_condattr_t.java │ │ │ ├── __darwin_pthread_handler_rec.java │ │ │ ├── __darwin_pthread_mutex_t.java │ │ │ ├── __darwin_pthread_mutexattr_t.java │ │ │ ├── __darwin_pthread_once_t.java │ │ │ ├── __darwin_pthread_rwlock_t.java │ │ │ ├── __darwin_pthread_rwlockattr_t.java │ │ │ ├── __mbstate_t.java │ │ │ ├── _opaque_pthread_attr_t.java │ │ │ ├── _opaque_pthread_cond_t.java │ │ │ ├── _opaque_pthread_condattr_t.java │ │ │ ├── _opaque_pthread_mutex_t.java │ │ │ ├── _opaque_pthread_mutexattr_t.java │ │ │ ├── _opaque_pthread_once_t.java │ │ │ ├── _opaque_pthread_rwlock_t.java │ │ │ ├── _opaque_pthread_rwlockattr_t.java │ │ │ ├── _opaque_pthread_t.java │ │ │ ├── decode_h.java │ │ │ └── imaxdiv_t.java │ │ │ └── webpdemux │ │ │ ├── WebPAnimDecoderOptions.java │ │ │ ├── WebPAnimInfo.java │ │ │ ├── WebPBitstreamFeatures.java │ │ │ ├── WebPChunkIterator.java │ │ │ ├── WebPData.java │ │ │ ├── WebPDecBuffer.java │ │ │ ├── WebPDecoderConfig.java │ │ │ ├── WebPDecoderOptions.java │ │ │ ├── WebPIterator.java │ │ │ ├── WebPRGBABuffer.java │ │ │ ├── WebPYUVABuffer.java │ │ │ ├── __darwin_mbstate_t.java │ │ │ ├── __darwin_pthread_attr_t.java │ │ │ ├── __darwin_pthread_cond_t.java │ │ │ ├── __darwin_pthread_condattr_t.java │ │ │ ├── __darwin_pthread_handler_rec.java │ │ │ ├── __darwin_pthread_mutex_t.java │ │ │ ├── __darwin_pthread_mutexattr_t.java │ │ │ ├── __darwin_pthread_once_t.java │ │ │ ├── __darwin_pthread_rwlock_t.java │ │ │ ├── __darwin_pthread_rwlockattr_t.java │ │ │ ├── __mbstate_t.java │ │ │ ├── _opaque_pthread_attr_t.java │ │ │ ├── _opaque_pthread_cond_t.java │ │ │ ├── _opaque_pthread_condattr_t.java │ │ │ ├── _opaque_pthread_mutex_t.java │ │ │ ├── _opaque_pthread_mutexattr_t.java │ │ │ ├── _opaque_pthread_once_t.java │ │ │ ├── _opaque_pthread_rwlock_t.java │ │ │ ├── _opaque_pthread_rwlockattr_t.java │ │ │ ├── _opaque_pthread_t.java │ │ │ ├── demux_h.java │ │ │ └── imaxdiv_t.java │ └── resources │ │ └── META-INF │ │ └── services │ │ └── javax.imageio.spi.ImageReaderSpi │ └── test │ ├── java │ └── com │ │ └── github │ │ └── gotson │ │ └── nightmonkeys │ │ └── webp │ │ └── imageio │ │ └── plugins │ │ └── WebpImageReaderTest.java │ ├── java22 │ └── com │ │ └── github │ │ └── gotson │ │ └── nightmonkeys │ │ └── webp │ │ └── imageio │ │ └── plugins │ │ └── WebpImageReaderTest.java │ └── resources │ └── webp │ ├── 1.webp │ ├── 1_webp_a.webp │ ├── 1_webp_ll.webp │ ├── 2_webp_a.webp │ ├── 2_webp_ll.webp │ ├── 2_webp_ll_alt.webp │ ├── 3_webp_a.webp │ ├── 3_webp_ll.webp │ ├── 4_webp_a.webp │ ├── 4_webp_ll.webp │ ├── 5.webp │ ├── 5_webp_a.webp │ ├── 5_webp_ll.webp │ ├── alpha_filter.webp │ ├── animated-banana.webp │ ├── animated-webp-supported.webp │ ├── blue_tile.webp │ ├── bug3.webp │ ├── gray.webp │ ├── photo-iccp-adobergb.webp │ ├── segment01.webp │ ├── segment02.webp │ ├── segment03.webp │ ├── small_13x1.webp │ ├── small_1x1.webp │ ├── small_1x13.webp │ ├── small_31x13.webp │ ├── test.webp │ └── very_short.webp ├── settings.gradle └── test-libraries └── windows └── x64 ├── aom.dll ├── brotlicommon.dll ├── brotlidec.dll ├── brotlienc.dll ├── dav1d.dll ├── heif.dll ├── hwy.dll ├── jxl.dll ├── jxl_threads.dll ├── lcms2.dll ├── libde265.dll ├── libsharpyuv.dll ├── libwebp.dll ├── libwebpdecoder.dll ├── libwebpmux.dll ├── libx265.dll ├── webp.dll ├── webpdemux.dll └── zlib1.dll /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "gradle" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | 8 | # Maintain dependencies for GitHub Actions 9 | - package-ecosystem: "github-actions" 10 | directory: "/" 11 | schedule: 12 | interval: "weekly" 13 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches-ignore: 7 | - 'dependabot/**' 8 | workflow_dispatch: 9 | inputs: 10 | perform_release: 11 | description: 'Perform release' 12 | default: false 13 | type: boolean 14 | bump: 15 | description: 'Bump type' 16 | required: false 17 | default: 'next' 18 | type: choice 19 | options: 20 | - 'next' 21 | - 'major' 22 | - 'minor' 23 | - 'patch' 24 | 25 | jobs: 26 | test: 27 | runs-on: ${{ matrix.os }} 28 | strategy: 29 | matrix: 30 | os: [ ubuntu-latest, macos-13, windows-latest ] 31 | fail-fast: false 32 | name: Test ${{ matrix.os }} 33 | steps: 34 | - uses: actions/checkout@v4 35 | - name: Set up Homebrew for Linux/Mac 36 | if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') 37 | id: set-up-homebrew 38 | uses: Homebrew/actions/setup-homebrew@master 39 | - name: Install libraries for Linux/Mac 40 | if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') 41 | run: brew install webp jpeg-xl libheif 42 | env: 43 | HOMEBREW_NO_INSTALL_CLEANUP: 1 44 | HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 45 | - name: Setup test-libraries in path for Windows 46 | if: contains(matrix.os, 'windows') 47 | run: Add-Content $env:GITHUB_PATH $env:GITHUB_WORKSPACE\test-libraries\windows\x64\ 48 | - name: Setup Java 49 | uses: actions/setup-java@v4 50 | with: 51 | distribution: 'temurin' 52 | java-version: '22' 53 | - name: Setup Gradle 54 | uses: gradle/actions/setup-gradle@v4 55 | - name: Gradle build 56 | run: ./gradlew build 57 | env: 58 | LD_LIBRARY_PATH: /home/linuxbrew/.linuxbrew/lib 59 | JAVA_LIBRARY_PATH: /usr/local/lib/ 60 | - name: Upload Unit Test Reports 61 | if: always() 62 | uses: actions/upload-artifact@v4 63 | with: 64 | name: test-reports-${{ matrix.os }} 65 | path: '**/build/reports/tests/' 66 | 67 | version: 68 | runs-on: macos-latest 69 | if: github.repository_owner == 'gotson' && github.ref == 'refs/heads/main' 70 | outputs: 71 | version_current: ${{ steps.versions.outputs.version_current }} 72 | version_next: ${{ steps.versions.outputs.version_next }} 73 | should_release: ${{ steps.versions.outputs.should_release }} 74 | steps: 75 | - uses: actions/checkout@v4 76 | with: 77 | fetch-depth: 0 78 | - name: Set up Homebrew 79 | id: set-up-homebrew 80 | uses: Homebrew/actions/setup-homebrew@master 81 | - name: Install svu 82 | run: brew install caarlos0/tap/svu 83 | - name: Compute next version for release 84 | if: inputs.perform_release 85 | run: | 86 | echo "VERSION_NEXT=`svu ${{ inputs.bump }}`" | tee -a $GITHUB_ENV 87 | echo "VERSION_NEXT_SUFFIX=`svu ${{ inputs.bump }}`" | tee -a $GITHUB_ENV 88 | - name: Compute next version for snapshot 89 | if: inputs.perform_release != true 90 | run: | 91 | echo "VERSION_NEXT=`svu next`" | tee -a $GITHUB_ENV 92 | echo "VERSION_NEXT_SUFFIX=`svu next`-SNAPSHOT" | tee -a $GITHUB_ENV 93 | - name: Set Versions 94 | id: versions 95 | run: | 96 | echo "version_current=`svu current`" >> $GITHUB_OUTPUT 97 | echo "version_next=${{ env.VERSION_NEXT_SUFFIX }}" >> $GITHUB_OUTPUT 98 | [[ `svu current` != ${{ env.VERSION_NEXT }} ]] && echo "should_release=true" >> $GITHUB_OUTPUT || echo 99 | 100 | release: 101 | needs: [ version, test ] 102 | runs-on: ubuntu-latest 103 | if: needs.version.outputs.should_release 104 | steps: 105 | - uses: actions/checkout@v4 106 | with: 107 | fetch-depth: 0 108 | - name: Display versions 109 | run: | 110 | echo "Current version: ${{ needs.version.outputs.version_current }}, should release: ${{ needs.version.outputs.version_next }}" 111 | - name: Update version in gradle.properties 112 | run: echo "version=${{ needs.version.outputs.version_next }}" > gradle.properties 113 | - name: Setup Java 114 | uses: actions/setup-java@v4 115 | with: 116 | distribution: 'temurin' 117 | java-version: '22' 118 | - name: Setup Gradle 119 | uses: gradle/actions/setup-gradle@v4 120 | - name: Nexus publish 121 | run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository 122 | env: 123 | ORG_GRADLE_PROJECT_signingKey: ${{ secrets.GPG_KEY }} 124 | ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.GPG_PASSPHRASE }} 125 | ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.MAVENCENTRAL_USER }} 126 | ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.MAVENCENTRAL_PASSWORD }} 127 | - name: Release commit and push 128 | uses: EndBug/add-and-commit@v9 129 | if: inputs.perform_release 130 | with: 131 | message: 'chore(release): ${{ needs.version.outputs.version_next }} [skip ci]' 132 | default_author: github_actions 133 | - name: JReleaser full release 134 | run: ./gradlew jreleaserFullRelease 135 | if: inputs.perform_release 136 | env: 137 | JRELEASER_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 138 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | .classpath 3 | .project 4 | .settings/ 5 | target/ 6 | bin/ 7 | 8 | ### IntelliJ IDEA 9 | !.idea/ 10 | .idea/* 11 | !/.idea/runConfigurations/ 12 | *.iws 13 | *.iml 14 | *.ipr 15 | 16 | ### NetBeans 17 | nbproject/private/ 18 | build/ 19 | nbbuild/ 20 | dist/ 21 | nbdist/ 22 | .nb-gradle/ 23 | 24 | ### Gradle 25 | .gradle 26 | !gradle/wrapper/gradle-wrapper.jar 27 | 28 | ### NodeJS 29 | node_modules -------------------------------------------------------------------------------- /.svu.yml: -------------------------------------------------------------------------------- 1 | tag: 2 | prefix: '' 3 | pattern: 'v[0-9]*' -------------------------------------------------------------------------------- /DEVELOPING.md: -------------------------------------------------------------------------------- 1 | # Development guidelines 2 | 3 | ## Requirements 4 | 5 | NightMonkeys relies on native libraries being installed on your system, and for the path of those libraries to be available for Java. Check the README of each plugin for details on how to install the required library for different OSes. 6 | 7 | You will also need a version of Java to run Gradle. Gradle is configured to use the Java toolchains feature, and will download the necessary JDK if needed. 8 | 9 | ## Tests 10 | 11 | There are 3 test tasks per project: 12 | - `test`: will test the Java 8 classes 13 | - `java21Test`: will test the Java 21 classes 14 | - `noLibTest`: will test the Java 21 classes, but without the path to the libraries. 15 | 16 | Run `./gradlew check` to run them all. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Gauthier 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/gotson/NightMonkeys/ci.yml?branch=main&style=flat-square)](https://github.com/gotson/NightMonkeys/actions/workflows/ci.yml) 2 | [![Maven Central](https://img.shields.io/maven-central/v/com.github.gotson.nightmonkeys/imageio-jxl?color=blue&style=flat-square)](https://search.maven.org/search?q=g:com.github.gotson.nightmonkeys) 3 | [![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/com.github.gotson.nightmonkeys/imageio-jxl?color=blue&label=maven-snapshot&server=https%3A%2F%2Foss.sonatype.org&style=flat-square)](https://oss.sonatype.org/content/repositories/snapshots/com/github/gotson/nightmonkeys/) 4 | 5 | # NightMonkeys 6 | 7 | A collection of ImageIO plugins, adding support for newer image formats. NightMonkeys uses the Foreign Linker API 8 | available since JDK 22 to access native libraries. 9 | 10 | ## How it works 11 | 12 | NightMonkeys plugins are released as multi-release JARs: 13 | 14 | - with Java < 22, a no-op version of the plugin will unregister itself on load, basically doing nothing 15 | - with Java 22+, the plugin will be available 16 | 17 | This lets you add the dependencies in your project whatever the JDK used, and still enable the plugin at runtime if the necessary JDK is used. 18 | 19 | ## Supported formats 20 | 21 | | Plugin | Format | Read | Write | Metadata | TwelveMonkeys Tests | Notes | 22 | |----------------------|----------------------------------------------------------------------------------------------------------------------|------|-------|----------|---------------------|------------------------------------| 23 | | [jxl](imageio-jxl) | [Jpeg XL](https://jpeg.org/jpegxl/) | ✔ | - | - | ✔ | See limitations in the plugin page | 24 | | [webp](imageio-webp) | [WebP](https://developers.google.com/speed/webp) | ✔ | - | - | ✔ | See limitations in the plugin page | 25 | | [heif](imageio-heif) | [HEIF](https://en.wikipedia.org/wiki/High_Efficiency_Image_File_Format) & [AVIF](https://en.wikipedia.org/wiki/AVIF) | ✔ | ✔ | - | ✔ | See limitations in the plugin page | 26 | 27 | When possible, the plugins will use the extensive test suite 28 | from [TwelveMonkeys](https://github.com/haraldk/TwelveMonkeys), which covers much more test cases than simple 29 | decoding/encoding. 30 | 31 | ## Requirements 32 | 33 | In order for the plugins to run properly, you will need to: 34 | 35 | - Run Java 22 with the following options: 36 | 37 | ``` 38 | --enable-native-access=ALL-UNNAMED 39 | ``` 40 | 41 | - Make sure the path to the directory containing the native libraries is contained in the Java system 42 | property `java.library.path` (check 43 | also [this](https://stackoverflow.com/questions/20038789/default-java-library-path)). 44 | - For Linux, normally it works fine when installed from a package manager. You can add the libraries' path to 45 | the `LD_LIBRARY_PATH` environment variable. 46 | - For Mac, if using HomeBrew, you will need to set `JAVA_LIBRARY_PATH` to `/usr/local/lib/` or `/opt/homebrew/lib/`. 47 | 48 | ## Installation 49 | 50 | ### Gradle 51 | 52 | ```groovy 53 | runtimeOnly "com.github.gotson.nightmonkeys:imageio-{plugin}:{version}" 54 | ``` 55 | 56 | ### Gradle (Kotlin DSL) 57 | 58 | ```kotlin 59 | runtimeOnly("com.github.gotson.nightmonkeys:imageio-{plugin}:{version}") 60 | ``` 61 | 62 | ### Maven 63 | 64 | ```xml 65 | 66 | com.github.gotson.nightmonkeys 67 | imageio-{plugin} 68 | {version} 69 | runtime 70 | 71 | ``` 72 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'base' 3 | id 'io.github.gradle-nexus.publish-plugin' version '2.0.0' 4 | id 'me.champeau.mrjar' version '0.1.1' apply(false) 5 | id 'org.jreleaser' version '1.18.0' 6 | id 'com.github.ben-manes.versions' version '0.52.0' 7 | } 8 | 9 | nexusPublishing { 10 | repositories { 11 | // see https://central.sonatype.org/publish/publish-portal-ossrh-staging-api/#configuration 12 | sonatype { 13 | nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/")) 14 | snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/")) 15 | } 16 | } 17 | } 18 | 19 | def isNonStable = { String version -> 20 | def stableKeyword = ['RELEASE', 'FINAL', 'GA'].any { it -> version.toUpperCase().contains(it) } 21 | def unstableKeyword = ['ALPHA', 'RC'].any { it -> version.toUpperCase().contains(it) } 22 | def regex = /^[0-9,.v-]+(-r)?$/ 23 | def isStable = stableKeyword || version ==~ regex 24 | return unstableKeyword || !isStable 25 | } 26 | 27 | allprojects { 28 | group = 'com.github.gotson.nightmonkeys' 29 | repositories { 30 | mavenCentral() 31 | } 32 | 33 | apply plugin: 'com.github.ben-manes.versions' 34 | tasks.named("dependencyUpdates").configure { 35 | rejectVersionIf { 36 | isNonStable(it.candidate.version) && !isNonStable(it.currentVersion) 37 | } 38 | gradleReleaseChannel = 'current' 39 | checkConstraints = true 40 | } 41 | } 42 | 43 | subprojects { 44 | apply from: "${rootDir}/gradle/publish.gradle" 45 | if (it.name != 'imageio-common') { 46 | apply from: "${rootDir}/gradle/mrjar.gradle" 47 | apply from: "${rootDir}/gradle/dependencies.gradle" 48 | } 49 | } 50 | 51 | jreleaser { 52 | project { 53 | description = 'NightMonkeys :: ImageIO' 54 | copyright = 'Gauthier Roebroeck' 55 | } 56 | release { 57 | github { 58 | discussionCategoryName = 'Announcements' 59 | 60 | changelog { 61 | formatted = 'ALWAYS' 62 | preset = 'conventional-commits' 63 | skipMergeCommits = true 64 | links = true 65 | format = '- {{#commitIsConventional}}{{#conventionalCommitIsBreakingChange}}🚨 {{/conventionalCommitIsBreakingChange}}{{#conventionalCommitScope}}**{{conventionalCommitScope}}**: {{/conventionalCommitScope}}{{conventionalCommitDescription}}{{#conventionalCommitBreakingChangeContent}}: *{{conventionalCommitBreakingChangeContent}}*{{/conventionalCommitBreakingChangeContent}} ({{commitShortHash}}){{/commitIsConventional}}{{^commitIsConventional}}{{commitTitle}} ({{commitShortHash}}){{/commitIsConventional}}{{#commitHasIssues}}, closes{{#commitIssues}} {{issue}}{{/commitIssues}}{{/commitHasIssues}}' 66 | contributors { 67 | enabled = false 68 | } 69 | hide { 70 | uncategorized = true 71 | contributors = ['[bot]', 'github-actions', 'GitHub'] 72 | } 73 | excludeLabels = ['chore'] 74 | category { 75 | title = '🏎 Perf' 76 | key = 'perf' 77 | labels = ['perf'] 78 | order = 25 79 | } 80 | labeler { 81 | label = 'perf' 82 | title = 'regex:^(?:perf(?:\\(.*\\))?!?):\\s.*' 83 | order = 120 84 | } 85 | extraProperties.put('categorizeScopes', true) 86 | } 87 | 88 | issues { 89 | enabled = true 90 | comment = '🎉 This issue has been resolved in `{{tagName}}` ([Release Notes]({{releaseNotesUrl}}))' 91 | applyMilestone = 'ALWAYS' 92 | label { 93 | name = 'released' 94 | description = 'Issue has been released' 95 | color = '#ededed' 96 | } 97 | } 98 | } 99 | } 100 | } 101 | 102 | wrapper { 103 | gradleVersion = '8.14' 104 | distributionType = Wrapper.DistributionType.ALL 105 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | version=1.0.0 2 | -------------------------------------------------------------------------------- /gradle/dependencies.gradle: -------------------------------------------------------------------------------- 1 | tasks.withType(Test) { 2 | useJUnitPlatform() 3 | } 4 | 5 | dependencies { 6 | implementation 'com.twelvemonkeys.imageio:imageio-core:3.12.0' 7 | implementation 'org.slf4j:slf4j-api:1.7.36' 8 | implementation project(':imageio-common') 9 | 10 | testImplementation(testFixtures(project(':imageio-common'))) 11 | testImplementation 'org.assertj:assertj-core:3.27.3' 12 | testImplementation 'org.junit.jupiter:junit-jupiter:5.12.0' 13 | testRuntimeOnly 'org.junit.platform:junit-platform-launcher' 14 | testImplementation 'org.slf4j:slf4j-simple:1.7.36' 15 | testImplementation 'org.mockito:mockito-core:4.8.1' 16 | testImplementation 'org.apache.commons:commons-collections4:4.4' 17 | } 18 | -------------------------------------------------------------------------------- /gradle/mrjar.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'me.champeau.mrjar' 2 | 3 | multiRelease { 4 | targetVersions 8, 22 5 | } 6 | 7 | java22Test { 8 | jvmArgs += ["--enable-native-access=ALL-UNNAMED"] 9 | } 10 | 11 | configurations { 12 | java22Implementation.extendsFrom(implementation) 13 | } 14 | 15 | def noLibTestTask = tasks.register('noLibTest', Test) { 16 | description = 'Runs tests without lib' 17 | group = 'verification' 18 | 19 | classpath = files(jar.archiveFile.get().asFile) + 20 | configurations[sourceSets.java22.runtimeClasspathConfigurationName] + 21 | configurations[sourceSets.test.runtimeClasspathConfigurationName] + 22 | sourceSets.test.output 23 | testClassesDirs = sourceSets.test.output.classesDirs 24 | 25 | jvmArgs += ["--enable-native-access=ALL-UNNAMED"] 26 | systemProperty "java.library.path", '' 27 | javaLauncher = javaToolchains.launcherFor { 28 | languageVersion = JavaLanguageVersion.of(22) 29 | } 30 | 31 | dependsOn jar 32 | } 33 | 34 | tasks.named('check') { 35 | dependsOn(noLibTestTask) 36 | } 37 | -------------------------------------------------------------------------------- /gradle/publish.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'maven-publish' 2 | apply plugin: 'java-library' 3 | apply plugin: 'signing' 4 | 5 | java { 6 | withJavadocJar() 7 | withSourcesJar() 8 | } 9 | 10 | jar { 11 | manifest { 12 | attributes( 13 | 'Implementation-Version': "$project.version", 14 | 'Implementation-Vendor': "NightMonkeys" 15 | ) 16 | } 17 | } 18 | 19 | publishing { 20 | repositories { 21 | mavenLocal() 22 | } 23 | 24 | publications { 25 | mavenJava(MavenPublication) { 26 | from components.java 27 | versionMapping { 28 | usage('java-api') { 29 | fromResolutionOf('runtimeClasspath') 30 | } 31 | usage('java-runtime') { 32 | fromResolutionResult() 33 | } 34 | } 35 | pom { 36 | name = project.name 37 | description = 'NightMonkeys :: ImageIO' 38 | url = 'https://github.com/gotson/NightMonkeys' 39 | inceptionYear = '2022' 40 | 41 | licenses { 42 | license { 43 | name = 'MIT' 44 | url = 'https://github.com/gotson/NightMonkeys/blob/main/LICENSE' 45 | } 46 | } 47 | developers { 48 | developer { 49 | id = 'gotson' 50 | name = 'Gauthier Roebroeck' 51 | } 52 | } 53 | scm { 54 | url = 'https://github.com/gotson/NightMonkeys.git' 55 | } 56 | } 57 | } 58 | } 59 | } 60 | 61 | signing { 62 | required { false } 63 | def signingKey = findProperty('signingKey') 64 | def signingPassword = findProperty('signingPassword') 65 | useInMemoryPgpKeys(signingKey, signingPassword) 66 | sign publishing.publications.mavenJava 67 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/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-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /imageio-common/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | apply plugin: 'java-test-fixtures' 3 | 4 | java { 5 | toolchain { 6 | languageVersion = JavaLanguageVersion.of(8) 7 | } 8 | } 9 | 10 | dependencies { 11 | testFixturesImplementation 'com.twelvemonkeys.imageio:imageio-core:3.12.0' 12 | testFixturesImplementation 'org.junit.jupiter:junit-jupiter:5.12.2' 13 | testFixturesImplementation 'org.mockito:mockito-core:4.11.0' 14 | testFixturesImplementation 'org.assertj:assertj-core:3.27.3' 15 | testFixturesImplementation 'org.apache.commons:commons-collections4:4.5.0' 16 | } -------------------------------------------------------------------------------- /imageio-common/src/main/java/com/github/gotson/nightmonkeys/common/imageio/IIOUtil.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.common.imageio; 2 | 3 | import javax.imageio.stream.ImageInputStream; 4 | import java.io.ByteArrayOutputStream; 5 | import java.io.IOException; 6 | 7 | public final class IIOUtil { 8 | 9 | private IIOUtil() {} 10 | 11 | public static byte[] byteArrayFromStream(ImageInputStream stream) throws IOException { 12 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); 13 | final byte[] buf = new byte[8192]; 14 | int n; 15 | while (0 < (n = stream.read(buf))) { 16 | bos.write(buf, 0, n); 17 | } 18 | return bos.toByteArray(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /imageio-common/src/main/java/com/github/gotson/nightmonkeys/common/imageio/ImageReaderSpiBase.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.common.imageio; 2 | 3 | import javax.imageio.spi.ImageReaderSpi; 4 | 5 | public abstract class ImageReaderSpiBase extends ImageReaderSpi { 6 | protected ImageReaderSpiBase(final ProviderInfo provider) { 7 | super( 8 | provider.getVendorName(), 9 | provider.getVersion(), 10 | provider.getFormatNames(), 11 | provider.getSuffixes(), 12 | provider.getMimeTypes(), 13 | provider.getReaderClassName(), 14 | provider.getInputTypes(), 15 | provider.getWriterSpiClassNames(), 16 | provider.isSupportsStandardStreamMetadata(), 17 | provider.getNativeStreamMetadataFormatName(), 18 | provider.getNativeStreamMetadataFormatClassName(), 19 | provider.getExtraStreamMetadataFormatNames(), 20 | provider.getExtraStreamMetadataFormatClassNames(), 21 | provider.isSupportsStandardImageMetadata(), 22 | provider.getNativeImageMetadataFormatName(), 23 | provider.getNativeImageMetadataFormatClassName(), 24 | provider.getExtraImageMetadataFormatNames(), 25 | provider.getExtraImageMetadataFormatClassNames() 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /imageio-common/src/main/java/com/github/gotson/nightmonkeys/common/imageio/ImageWriterSpiBase.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.common.imageio; 2 | 3 | import javax.imageio.spi.ImageWriterSpi; 4 | 5 | public abstract class ImageWriterSpiBase extends ImageWriterSpi { 6 | protected ImageWriterSpiBase(final ProviderInfo provider) { 7 | super( 8 | provider.getVendorName(), 9 | provider.getVersion(), 10 | provider.getFormatNames(), 11 | provider.getSuffixes(), 12 | provider.getMimeTypes(), 13 | provider.getWriterClassName(), 14 | provider.getOutputTypes(), 15 | provider.getReaderSpiClassNames(), 16 | provider.isSupportsStandardStreamMetadata(), 17 | provider.getNativeStreamMetadataFormatName(), 18 | provider.getNativeStreamMetadataFormatClassName(), 19 | provider.getExtraStreamMetadataFormatNames(), 20 | provider.getExtraStreamMetadataFormatClassNames(), 21 | provider.isSupportsStandardImageMetadata(), 22 | provider.getNativeImageMetadataFormatName(), 23 | provider.getNativeImageMetadataFormatClassName(), 24 | provider.getExtraImageMetadataFormatNames(), 25 | provider.getExtraImageMetadataFormatClassNames() 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /imageio-common/src/main/java/com/github/gotson/nightmonkeys/common/imageio/ProviderInfo.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.common.imageio; 2 | 3 | import javax.imageio.stream.ImageInputStream; 4 | import javax.imageio.stream.ImageOutputStream; 5 | 6 | public class ProviderInfo { 7 | private final String vendorName = "NightMonkeys"; 8 | private final String version = "1.0.0"; 9 | private final String[] formatNames; 10 | private final String[] suffixes; 11 | private final String[] mimeTypes; 12 | private final String readerClassName; 13 | private final String[] readerSpiClassNames; 14 | private final Class[] inputTypes = new Class[] {ImageInputStream.class}; 15 | private final String writerClassName; 16 | private final String[] writerSpiClassNames; 17 | private final Class[] outputTypes = new Class[] {ImageOutputStream.class}; 18 | private final boolean supportsStandardStreamMetadata; 19 | private final String nativeStreamMetadataFormatName; 20 | private final String nativeStreamMetadataFormatClassName; 21 | private final String[] extraStreamMetadataFormatNames; 22 | private final String[] extraStreamMetadataFormatClassNames; 23 | private final boolean supportsStandardImageMetadata; 24 | private final String nativeImageMetadataFormatName; 25 | private final String nativeImageMetadataFormatClassName; 26 | private final String[] extraImageMetadataFormatNames; 27 | private final String[] extraImageMetadataFormatClassNames; 28 | 29 | public ProviderInfo( 30 | String[] formatNames, 31 | String[] suffixes, 32 | String[] mimeTypes, 33 | String readerClassName, 34 | String[] readerSpiClassNames, 35 | String writerClassName, 36 | String[] writerSpiClassNames, 37 | boolean supportsStandardStreamMetadata, 38 | String nativeStreamMetadataFormatName, 39 | String nativeStreamMetadataFormatClassName, 40 | String[] extraStreamMetadataFormatNames, 41 | String[] extraStreamMetadataFormatClassNames, 42 | boolean supportsStandardImageMetadata, 43 | String nativeImageMetadataFormatName, 44 | String nativeImageMetadataFormatClassName, 45 | String[] extraImageMetadataFormatNames, 46 | String[] extraImageMetadataFormatClassNames 47 | ) { 48 | this.formatNames = formatNames; 49 | this.suffixes = suffixes; 50 | this.mimeTypes = mimeTypes; 51 | this.readerClassName = readerClassName; 52 | this.readerSpiClassNames = readerSpiClassNames; 53 | this.writerClassName = writerClassName; 54 | this.writerSpiClassNames = writerSpiClassNames; 55 | this.supportsStandardStreamMetadata = supportsStandardStreamMetadata; 56 | this.nativeStreamMetadataFormatName = nativeStreamMetadataFormatName; 57 | this.nativeStreamMetadataFormatClassName = nativeStreamMetadataFormatClassName; 58 | this.extraStreamMetadataFormatNames = extraStreamMetadataFormatNames; 59 | this.extraStreamMetadataFormatClassNames = extraStreamMetadataFormatClassNames; 60 | this.supportsStandardImageMetadata = supportsStandardImageMetadata; 61 | this.nativeImageMetadataFormatName = nativeImageMetadataFormatName; 62 | this.nativeImageMetadataFormatClassName = nativeImageMetadataFormatClassName; 63 | this.extraImageMetadataFormatNames = extraImageMetadataFormatNames; 64 | this.extraImageMetadataFormatClassNames = extraImageMetadataFormatClassNames; 65 | } 66 | 67 | public String[] getExtraImageMetadataFormatClassNames() { 68 | return extraImageMetadataFormatClassNames; 69 | } 70 | 71 | public String[] getExtraImageMetadataFormatNames() { 72 | return extraImageMetadataFormatNames; 73 | } 74 | 75 | public String[] getExtraStreamMetadataFormatClassNames() { 76 | return extraStreamMetadataFormatClassNames; 77 | } 78 | 79 | public String[] getExtraStreamMetadataFormatNames() { 80 | return extraStreamMetadataFormatNames; 81 | } 82 | 83 | public String[] getFormatNames() { 84 | return formatNames; 85 | } 86 | 87 | public Class[] getInputTypes() { 88 | return inputTypes; 89 | } 90 | 91 | public String[] getMimeTypes() { 92 | return mimeTypes; 93 | } 94 | 95 | public String getNativeImageMetadataFormatClassName() { 96 | return nativeImageMetadataFormatClassName; 97 | } 98 | 99 | public String getNativeImageMetadataFormatName() { 100 | return nativeImageMetadataFormatName; 101 | } 102 | 103 | public String getNativeStreamMetadataFormatClassName() { 104 | return nativeStreamMetadataFormatClassName; 105 | } 106 | 107 | public String getNativeStreamMetadataFormatName() { 108 | return nativeStreamMetadataFormatName; 109 | } 110 | 111 | public Class[] getOutputTypes() { 112 | return outputTypes; 113 | } 114 | 115 | public String getReaderClassName() { 116 | return readerClassName; 117 | } 118 | 119 | public String[] getReaderSpiClassNames() { 120 | return readerSpiClassNames; 121 | } 122 | 123 | public String[] getSuffixes() { 124 | return suffixes; 125 | } 126 | 127 | public boolean isSupportsStandardImageMetadata() { 128 | return supportsStandardImageMetadata; 129 | } 130 | 131 | public boolean isSupportsStandardStreamMetadata() { 132 | return supportsStandardStreamMetadata; 133 | } 134 | 135 | public String getVendorName() { 136 | return vendorName; 137 | } 138 | 139 | public String getVersion() { 140 | return version; 141 | } 142 | 143 | public String getWriterClassName() { 144 | return writerClassName; 145 | } 146 | 147 | public String[] getWriterSpiClassNames() { 148 | return writerSpiClassNames; 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /imageio-common/src/testFixtures/java/com/github/gotson/nightmonkeys/common/imageio/NoOpImageReaderAbstractTest.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.common.imageio; 2 | 3 | import org.apache.commons.collections4.IteratorUtils; 4 | import org.junit.jupiter.api.BeforeAll; 5 | import org.junit.jupiter.api.TestInstance; 6 | import org.junit.jupiter.params.ParameterizedTest; 7 | import org.junit.jupiter.params.provider.MethodSource; 8 | 9 | import javax.imageio.ImageIO; 10 | import javax.imageio.ImageReader; 11 | import java.io.IOException; 12 | import java.net.URL; 13 | import java.util.ArrayList; 14 | import java.util.Arrays; 15 | import java.util.Enumeration; 16 | import java.util.List; 17 | import java.util.Spliterator; 18 | import java.util.Spliterators; 19 | import java.util.stream.StreamSupport; 20 | 21 | import static org.assertj.core.api.Assertions.assertThat; 22 | 23 | @TestInstance(TestInstance.Lifecycle.PER_CLASS) 24 | public abstract class NoOpImageReaderAbstractTest { 25 | private final ProviderInfo provider = createProvider(); 26 | 27 | protected abstract ProviderInfo createProvider(); 28 | 29 | private List getFormatNames() { 30 | return Arrays.asList(provider.getFormatNames()); 31 | } 32 | 33 | private List getSuffixes() { 34 | return Arrays.asList(provider.getSuffixes()); 35 | } 36 | 37 | private List getMIMETypes() { 38 | return Arrays.asList(provider.getMimeTypes()); 39 | } 40 | 41 | @BeforeAll 42 | public void printInformation() throws IOException { 43 | System.out.println("java.version: " + System.getProperty("java.version")); 44 | System.out.println("java.library.path: " + System.getProperty("java.library.path")); 45 | Enumeration spiFiles = ClassLoader.getSystemResources("META-INF/services/javax.imageio.spi.ImageReaderSpi"); 46 | Spliterator spliterator = Spliterators.spliteratorUnknownSize(IteratorUtils.asIterator(spiFiles), Spliterator.ORDERED); 47 | StreamSupport.stream(spliterator, false).forEachOrdered(x -> System.out.println("SPI File: " + x)); 48 | } 49 | 50 | @ParameterizedTest 51 | @MethodSource("getFormatNames") 52 | public void testReaderIsNotRegisteredByFormatName(String formatName) { 53 | ArrayList readers = new ArrayList<>(); 54 | ImageIO.getImageReadersByFormatName(formatName).forEachRemaining(readers::add); 55 | 56 | assertThat(readers).isEmpty(); 57 | } 58 | 59 | @ParameterizedTest 60 | @MethodSource("getSuffixes") 61 | public void testReaderIsNotRegisteredBySuffix(String suffix) { 62 | ArrayList readers = new ArrayList<>(); 63 | ImageIO.getImageReadersBySuffix(suffix).forEachRemaining(readers::add); 64 | 65 | assertThat(readers).isEmpty(); 66 | } 67 | 68 | @ParameterizedTest 69 | @MethodSource("getMIMETypes") 70 | public void testReaderIsNotRegisteredByMIMEType(String mimeType) { 71 | ArrayList readers = new ArrayList<>(); 72 | ImageIO.getImageReadersByMIMEType(mimeType).forEachRemaining(readers::add); 73 | 74 | assertThat(readers).isEmpty(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /imageio-common/src/testFixtures/java/com/github/gotson/nightmonkeys/common/imageio/NoOpImageWriterAbstractTest.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.common.imageio; 2 | 3 | import org.apache.commons.collections4.IteratorUtils; 4 | import org.junit.jupiter.api.BeforeAll; 5 | import org.junit.jupiter.api.TestInstance; 6 | import org.junit.jupiter.params.ParameterizedTest; 7 | import org.junit.jupiter.params.provider.MethodSource; 8 | 9 | import javax.imageio.ImageIO; 10 | import javax.imageio.ImageWriter; 11 | import java.io.IOException; 12 | import java.net.URL; 13 | import java.util.ArrayList; 14 | import java.util.Arrays; 15 | import java.util.Enumeration; 16 | import java.util.List; 17 | import java.util.Spliterator; 18 | import java.util.Spliterators; 19 | import java.util.stream.StreamSupport; 20 | 21 | import static org.assertj.core.api.Assertions.assertThat; 22 | 23 | @TestInstance(TestInstance.Lifecycle.PER_CLASS) 24 | public abstract class NoOpImageWriterAbstractTest { 25 | private final ProviderInfo provider = createProvider(); 26 | 27 | protected abstract ProviderInfo createProvider(); 28 | 29 | private List getFormatNames() { 30 | return Arrays.asList(provider.getFormatNames()); 31 | } 32 | 33 | private List getSuffixes() { 34 | return Arrays.asList(provider.getSuffixes()); 35 | } 36 | 37 | private List getMIMETypes() { 38 | return Arrays.asList(provider.getMimeTypes()); 39 | } 40 | 41 | @BeforeAll 42 | public void printInformation() throws IOException { 43 | System.out.println("java.version: " + System.getProperty("java.version")); 44 | System.out.println("java.library.path: " + System.getProperty("java.library.path")); 45 | Enumeration spiFiles = ClassLoader.getSystemResources("META-INF/services/javax.imageio.spi.ImageWriterSpi"); 46 | Spliterator spliterator = Spliterators.spliteratorUnknownSize(IteratorUtils.asIterator(spiFiles), Spliterator.ORDERED); 47 | StreamSupport.stream(spliterator, false).forEachOrdered(x -> System.out.println("SPI File: " + x)); 48 | } 49 | 50 | @ParameterizedTest 51 | @MethodSource("getFormatNames") 52 | public void testWriterIsNotRegisteredByFormatName(String formatName) { 53 | ArrayList writers = new ArrayList<>(); 54 | ImageIO.getImageWritersByFormatName(formatName).forEachRemaining(writers::add); 55 | 56 | assertThat(writers).isEmpty(); 57 | } 58 | 59 | @ParameterizedTest 60 | @MethodSource("getSuffixes") 61 | public void testWriterIsNotRegisteredBySuffix(String suffix) { 62 | ArrayList writers = new ArrayList<>(); 63 | ImageIO.getImageWritersBySuffix(suffix).forEachRemaining(writers::add); 64 | 65 | assertThat(writers).isEmpty(); 66 | } 67 | 68 | @ParameterizedTest 69 | @MethodSource("getMIMETypes") 70 | public void testWriterIsNotRegisteredByMIMEType(String mimeType) { 71 | ArrayList writers = new ArrayList<>(); 72 | ImageIO.getImageWritersByMIMEType(mimeType).forEachRemaining(writers::add); 73 | 74 | assertThat(writers).isEmpty(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /imageio-heif/README.md: -------------------------------------------------------------------------------- 1 | # ImageIO HEIF/AVIF plugin 2 | 3 | ## Requirements 4 | 5 | `libheif` version 1.16+ must be installed on the target system. 6 | 7 | ## Known installations methods 8 | 9 | - Homebrew (Mac & Linux): `brew install libheif` 10 | - apt (Linux): `apt-get install libheif-dev` 11 | 12 | ## Features 13 | 14 | - Decode HEIF and AVIF images 15 | - Encode HEIF and AVIF images 16 | 17 | ## Limitations 18 | 19 | - Decoding 20 | - HEIC and AVIF animations are not supported. A single image is returned. 21 | - Not implemented yet: 22 | - Color profiles 23 | - EXIF and XMP metadata 24 | - Thumbnails 25 | - Encoding 26 | - animations are not supported. A single image is written. 27 | - Not implemented yet: 28 | - Color profiles 29 | - EXIF and XMP metadata 30 | - Thumbnails 31 | 32 | ## Encoding parameters 33 | 34 | In order to configure the encoding, you will need to use a `HeifWriteParam`: 35 | 36 | ```java 37 | HeifWriteParam param = (HeifWriteParam) writer.getDefaultWriteParam(); 38 | // you need to check the available compression types, and choose the one you want 39 | String compressionType = param.getCompressionTypes()[0]; 40 | 41 | param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 42 | param.setCompressionType(compressionType); 43 | 44 | // lossless 45 | param.setLossless(true); 46 | 47 | // lossy 48 | param.setLossless(false); 49 | param.setCompressionQuality(0.75F); 50 | ``` 51 | 52 | ## Implementation notes 53 | 54 | The `panama` package bindings were generated using: 55 | - jextract 22 56 | - from the https://github.com/strukturag/libheif repository, version 1.16.0 57 | - based on the `heif.f` header file -------------------------------------------------------------------------------- /imageio-heif/build.gradle: -------------------------------------------------------------------------------- 1 | description = 'NightMonkeys :: ImageIO :: HEIF/AVIF plugin' 2 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java/com/github/gotson/nightmonkeys/heif/imageio/plugins/HeifImageReader.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.imageio.plugins; 2 | 3 | import javax.imageio.ImageReadParam; 4 | import javax.imageio.ImageReader; 5 | import javax.imageio.ImageTypeSpecifier; 6 | import javax.imageio.metadata.IIOMetadata; 7 | import javax.imageio.spi.ImageReaderSpi; 8 | import java.awt.image.BufferedImage; 9 | import java.io.IOException; 10 | import java.util.Iterator; 11 | 12 | public class HeifImageReader extends ImageReader { 13 | 14 | protected HeifImageReader(ImageReaderSpi originatingProvider) { 15 | super(originatingProvider); 16 | } 17 | 18 | /** 19 | * The number of images corresponds to the number of different resolutions that can be directly 20 | * decoded. 21 | */ 22 | @Override 23 | public int getNumImages(boolean allowSearch) { 24 | return 0; 25 | } 26 | 27 | @Override 28 | public int getWidth(int imageIndex) throws IOException { 29 | throw new IOException(); 30 | } 31 | 32 | @Override 33 | public int getHeight(int imageIndex) throws IOException { 34 | throw new IOException(); 35 | } 36 | 37 | @Override 38 | public Iterator getImageTypes(int imageIndex) throws IOException { 39 | throw new IOException(); 40 | } 41 | 42 | @Override 43 | public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException { 44 | throw new IOException(); 45 | } 46 | 47 | @Override 48 | public IIOMetadata getStreamMetadata() { 49 | return null; 50 | } 51 | 52 | @Override 53 | public IIOMetadata getImageMetadata(int imageIndex) { 54 | return null; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java/com/github/gotson/nightmonkeys/heif/imageio/plugins/HeifImageReaderSpi.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.ImageReaderSpiBase; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import javax.imageio.ImageReader; 8 | import javax.imageio.spi.ServiceRegistry; 9 | import java.util.Locale; 10 | 11 | public class HeifImageReaderSpi extends ImageReaderSpiBase { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(HeifImageReaderSpi.class); 14 | 15 | public HeifImageReaderSpi() { 16 | super(new HeifProviderInfo()); 17 | } 18 | 19 | @Override 20 | public void onRegistration(ServiceRegistry registry, Class category) { 21 | LOGGER.info("This plugin only supports Java 22, plugin will be disabled"); 22 | registry.deregisterServiceProvider(this); 23 | super.onRegistration(registry, category); 24 | } 25 | 26 | @Override 27 | public boolean canDecodeInput(Object input) { 28 | return false; 29 | } 30 | 31 | @Override 32 | public ImageReader createReaderInstance(Object extension) { 33 | return new HeifImageReader(this); 34 | } 35 | 36 | @Override 37 | public String getDescription(Locale locale) { 38 | return "Avif/Heif reader plugin based on libheif."; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java/com/github/gotson/nightmonkeys/heif/imageio/plugins/HeifImageWriter.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.imageio.plugins; 2 | 3 | import javax.imageio.IIOImage; 4 | import javax.imageio.ImageTypeSpecifier; 5 | import javax.imageio.ImageWriteParam; 6 | import javax.imageio.ImageWriter; 7 | import javax.imageio.metadata.IIOMetadata; 8 | import javax.imageio.spi.ImageWriterSpi; 9 | import java.io.IOException; 10 | 11 | public class HeifImageWriter extends ImageWriter { 12 | 13 | protected HeifImageWriter(ImageWriterSpi originatingProvider) { 14 | super(originatingProvider); 15 | } 16 | 17 | @Override 18 | public IIOMetadata getDefaultStreamMetadata(ImageWriteParam param) { 19 | return null; 20 | } 21 | 22 | @Override 23 | public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageType, ImageWriteParam param) { 24 | return null; 25 | } 26 | 27 | @Override 28 | public IIOMetadata convertStreamMetadata(IIOMetadata inData, ImageWriteParam param) { 29 | return null; 30 | } 31 | 32 | @Override 33 | public IIOMetadata convertImageMetadata(IIOMetadata inData, ImageTypeSpecifier imageType, ImageWriteParam param) { 34 | return null; 35 | } 36 | 37 | @Override 38 | public void write(IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param) throws IOException { 39 | throw new IOException(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java/com/github/gotson/nightmonkeys/heif/imageio/plugins/HeifImageWriterSpi.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.ImageWriterSpiBase; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import javax.imageio.ImageTypeSpecifier; 8 | import javax.imageio.ImageWriter; 9 | import javax.imageio.spi.ServiceRegistry; 10 | import java.util.Locale; 11 | 12 | public class HeifImageWriterSpi extends ImageWriterSpiBase { 13 | 14 | private static final Logger LOGGER = LoggerFactory.getLogger(HeifImageWriterSpi.class); 15 | 16 | public HeifImageWriterSpi() { 17 | super(new HeifProviderInfo()); 18 | } 19 | 20 | @Override 21 | public boolean canEncodeImage(ImageTypeSpecifier type) { 22 | return false; 23 | } 24 | 25 | @Override 26 | public ImageWriter createWriterInstance(Object extension) { 27 | return new HeifImageWriter(this); 28 | } 29 | 30 | @Override 31 | public void onRegistration(ServiceRegistry registry, Class category) { 32 | LOGGER.info("This plugin only supports Java 22, plugin will be disabled"); 33 | registry.deregisterServiceProvider(this); 34 | super.onRegistration(registry, category); 35 | } 36 | 37 | @Override 38 | public String getDescription(Locale locale) { 39 | return "Avif/Heif writer plugin based on libheif."; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java/com/github/gotson/nightmonkeys/heif/imageio/plugins/HeifProviderInfo.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.ProviderInfo; 4 | 5 | final class HeifProviderInfo extends ProviderInfo { 6 | HeifProviderInfo() { 7 | super( 8 | new String[] {"AVIF", "HEIF", "HEIC", "avif", "heif", "heic"}, 9 | new String[] {"heif", "heifs", "heic", "heics", "avci", "avcs", "avif", "HIF"}, 10 | new String[] {"image/avif", "image/heif", "image/heif-sequence", "image/heic", "image/heic-sequence"}, 11 | "com.github.gotson.nightmonkeys.heif.imageio.plugins.HeifImageReader", 12 | new String[] {"com.github.gotson.nightmonkeys.heif.imageio.plugins.HeifImageReaderSpi"}, 13 | "com.github.gotson.nightmonkeys.heif.imageio.plugins.HeifImageWriter", 14 | new String[] {"com.github.gotson.nightmonkeys.heif.imageio.plugins.HeifImageWriterSpi"}, 15 | false, 16 | null, 17 | null, 18 | null, 19 | null, 20 | false, 21 | null, 22 | null, 23 | null, 24 | null 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/BasicInfo.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif; 2 | 3 | import java.awt.color.ICC_Profile; 4 | 5 | public record BasicInfo( 6 | int width, 7 | int height, 8 | boolean hasAlpha, 9 | ICC_Profile iccProfile, 10 | int frameCount 11 | ) { 12 | } 13 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/HeifEncoder.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif; 2 | 3 | import com.github.gotson.nightmonkeys.heif.lib.enums.HeifCompressionFormat; 4 | 5 | public record HeifEncoder( 6 | String name, 7 | String id, 8 | HeifCompressionFormat format, 9 | boolean supportsLossless, 10 | boolean supportsLossy 11 | ) { 12 | } 13 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/HeifException.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif; 2 | 3 | public class HeifException extends Exception { 4 | public HeifException(String message) { 5 | super(message); 6 | } 7 | 8 | public HeifException(String message, Throwable cause) { 9 | super(message, cause); 10 | } 11 | 12 | public HeifException(Throwable e) { 13 | super(e); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/imageio/plugins/HeifImageReaderSpi.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.ImageReaderSpiBase; 4 | import com.github.gotson.nightmonkeys.heif.Heif; 5 | import com.github.gotson.nightmonkeys.heif.HeifException; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import javax.imageio.ImageIO; 10 | import javax.imageio.ImageReader; 11 | import javax.imageio.spi.ServiceRegistry; 12 | import javax.imageio.stream.ImageInputStream; 13 | import java.io.IOException; 14 | import java.util.Locale; 15 | 16 | public class HeifImageReaderSpi extends ImageReaderSpiBase { 17 | 18 | private static final Logger LOGGER = LoggerFactory.getLogger(HeifImageReaderSpi.class); 19 | 20 | public HeifImageReaderSpi() { 21 | super(new HeifProviderInfo()); 22 | } 23 | 24 | @Override 25 | public void onRegistration(ServiceRegistry registry, Class category) { 26 | if (!HeifLibraryLoader.loadLibrary()) { 27 | LOGGER.info("Deregistering service provider"); 28 | registry.deregisterServiceProvider(this); 29 | } 30 | super.onRegistration(registry, category); 31 | } 32 | 33 | @Override 34 | public boolean canDecodeInput(Object input) throws IOException { 35 | if (!(input instanceof ImageInputStream)) { 36 | input = ImageIO.createImageInputStream(input); 37 | } 38 | if (input == null) { 39 | return false; 40 | } 41 | 42 | try { 43 | return Heif.canDecode((ImageInputStream) input); 44 | } catch (HeifException e) { 45 | throw new IOException(e); 46 | } 47 | } 48 | 49 | @Override 50 | public ImageReader createReaderInstance(Object extension) { 51 | return new HeifImageReader(this); 52 | } 53 | 54 | @Override 55 | public String getDescription(Locale locale) { 56 | return "Avif/Heif reader plugin based on libheif."; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/imageio/plugins/HeifImageWriter.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.heif.Heif; 4 | import com.github.gotson.nightmonkeys.heif.HeifException; 5 | import com.twelvemonkeys.imageio.ImageWriterBase; 6 | 7 | import javax.imageio.IIOImage; 8 | import javax.imageio.ImageTypeSpecifier; 9 | import javax.imageio.ImageWriteParam; 10 | import javax.imageio.metadata.IIOMetadata; 11 | import javax.imageio.spi.ImageWriterSpi; 12 | import java.io.IOException; 13 | 14 | public class HeifImageWriter extends ImageWriterBase { 15 | 16 | protected HeifImageWriter(ImageWriterSpi originatingProvider) { 17 | super(originatingProvider); 18 | } 19 | 20 | @Override 21 | public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageType, ImageWriteParam param) { 22 | return null; 23 | } 24 | 25 | @Override 26 | public IIOMetadata convertImageMetadata(IIOMetadata inData, ImageTypeSpecifier imageType, ImageWriteParam param) { 27 | return null; 28 | } 29 | 30 | @Override 31 | public void write(IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param) throws IOException { 32 | assertOutput(); 33 | 34 | if (image.hasRaster()) { 35 | throw new UnsupportedOperationException("image has a Raster"); 36 | } 37 | 38 | processImageStarted(0); 39 | processImageProgress(0); 40 | 41 | try { 42 | Heif.encode(imageOutput, image, param); 43 | } catch (HeifException e) { 44 | throw new IOException(e); 45 | } 46 | 47 | processImageComplete(); 48 | } 49 | 50 | @Override 51 | public ImageWriteParam getDefaultWriteParam() { 52 | return new HeifWriteParam(getLocale()); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/imageio/plugins/HeifImageWriterSpi.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.ImageWriterSpiBase; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import javax.imageio.ImageTypeSpecifier; 8 | import javax.imageio.ImageWriter; 9 | import javax.imageio.spi.ServiceRegistry; 10 | import java.util.Locale; 11 | 12 | public class HeifImageWriterSpi extends ImageWriterSpiBase { 13 | 14 | private static final Logger LOGGER = LoggerFactory.getLogger(HeifImageWriterSpi.class); 15 | 16 | public HeifImageWriterSpi() { 17 | super(new HeifProviderInfo()); 18 | } 19 | 20 | @Override 21 | public boolean canEncodeImage(ImageTypeSpecifier type) { 22 | return true; 23 | } 24 | 25 | @Override 26 | public ImageWriter createWriterInstance(Object extension) { 27 | return new HeifImageWriter(this); 28 | } 29 | 30 | @Override 31 | public void onRegistration(ServiceRegistry registry, Class category) { 32 | if (!HeifLibraryLoader.loadLibrary()) { 33 | LOGGER.info("Deregistering service provider"); 34 | registry.deregisterServiceProvider(this); 35 | } 36 | super.onRegistration(registry, category); 37 | } 38 | 39 | @Override 40 | public String getDescription(Locale locale) { 41 | return "Avif/Heif writer plugin based on libheif."; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/imageio/plugins/HeifLibraryLoader.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.heif.Heif; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | class HeifLibraryLoader { 8 | private static final Logger LOGGER = LoggerFactory.getLogger(HeifLibraryLoader.class); 9 | private static Boolean libLoaded; 10 | 11 | synchronized static boolean loadLibrary() { 12 | if (libLoaded == null) { 13 | try { 14 | LOGGER.info("Loaded libheif v{}", Heif.getLibVersion()); 15 | if (Heif.isLibVersionSupported()) { 16 | libLoaded = true; 17 | return true; 18 | } else { 19 | LOGGER.warn("libheif version is not supported"); 20 | } 21 | } catch (UnsatisfiedLinkError e) { 22 | LOGGER.warn("Could not load libheif, plugin will be disabled. {}", e.getMessage()); 23 | } catch (ExceptionInInitializerError e) { 24 | LOGGER.warn("Native access is disabled, plugin will be disabled. Try adding JVM arguments: --enable-native-access=ALL-UNNAMED"); 25 | } catch (Exception e) { 26 | LOGGER.warn("Unknown error", e); 27 | } 28 | libLoaded = false; 29 | } 30 | return libLoaded; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/imageio/plugins/HeifWriteParam.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.heif.Heif; 4 | import com.github.gotson.nightmonkeys.heif.HeifException; 5 | 6 | import javax.imageio.ImageWriteParam; 7 | import java.util.Locale; 8 | 9 | public final class HeifWriteParam extends ImageWriteParam { 10 | private boolean lossless; 11 | 12 | public HeifWriteParam(final Locale locale) { 13 | super(locale); 14 | 15 | try { 16 | compressionTypes = Heif.getAvailableEncoders() 17 | .stream() 18 | .map(it -> it.format().name()) 19 | .distinct() 20 | .toArray(String[]::new); 21 | } catch (HeifException e) { 22 | System.err.println("Could not get available encoders"); 23 | } 24 | 25 | canWriteCompressed = true; 26 | lossless = true; 27 | } 28 | 29 | public boolean isLossless() { 30 | return lossless; 31 | } 32 | 33 | public void setLossless(boolean lossless) { 34 | this.lossless = lossless; 35 | } 36 | 37 | @Override 38 | public boolean isCompressionLossless() { 39 | return lossless; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/HeifError.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.lib; 2 | 3 | import com.github.gotson.nightmonkeys.heif.lib.enums.HeifErrorCode; 4 | import com.github.gotson.nightmonkeys.heif.lib.enums.HeifSuberrorCode; 5 | import com.github.gotson.nightmonkeys.heif.lib.panama.heif_error; 6 | 7 | import java.lang.foreign.MemorySegment; 8 | 9 | public record HeifError( 10 | HeifErrorCode code, 11 | HeifSuberrorCode subcode, 12 | String message 13 | ) { 14 | public static HeifError from(MemorySegment segment) { 15 | return new HeifError( 16 | HeifErrorCode.fromId(heif_error.code(segment)), 17 | HeifSuberrorCode.fromId(heif_error.subcode(segment)), 18 | heif_error.message(segment).getString(0) 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/enums/HeifChannel.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.lib.enums; 2 | 3 | import com.github.gotson.nightmonkeys.heif.lib.panama.heif_h; 4 | 5 | public enum HeifChannel { 6 | HEIF_CHANNEL_Y(heif_h.heif_channel_Y()), 7 | HEIF_CHANNEL_CB(heif_h.heif_channel_Cb()), 8 | HEIF_CHANNEL_CR(heif_h.heif_channel_Cr()), 9 | HEIF_CHANNEL_R(heif_h.heif_channel_R()), 10 | HEIF_CHANNEL_G(heif_h.heif_channel_G()), 11 | HEIF_CHANNEL_B(heif_h.heif_channel_B()), 12 | HEIF_CHANNEL_ALPHA(heif_h.heif_channel_Alpha()), 13 | HEIF_CHANNEL_INTERLEAVED(heif_h.heif_channel_interleaved()), 14 | ; 15 | 16 | private final int val; 17 | 18 | HeifChannel(int val) { 19 | this.val = val; 20 | } 21 | 22 | public int intValue() { 23 | return val; 24 | } 25 | 26 | public static HeifChannel fromId(int id) { 27 | for (HeifChannel type : values()) { 28 | if (type.intValue() == id) { 29 | return type; 30 | } 31 | } 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/enums/HeifChroma.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.lib.enums; 2 | 3 | import com.github.gotson.nightmonkeys.heif.lib.panama.heif_h; 4 | 5 | public enum HeifChroma { 6 | HEIF_CHROMA_UNDEFINED(heif_h.heif_chroma_undefined()), 7 | HEIF_CHROMA_MONOCHROME(heif_h.heif_chroma_monochrome()), 8 | HEIF_CHROMA_420(heif_h.heif_chroma_420()), 9 | HEIF_CHROMA_422(heif_h.heif_chroma_422()), 10 | HEIF_CHROMA_444(heif_h.heif_chroma_444()), 11 | HEIF_CHROMA_INTERLEAVED_RGB(heif_h.heif_chroma_interleaved_RGB()), 12 | HEIF_CHROMA_INTERLEAVED_RGBA(heif_h.heif_chroma_interleaved_RGBA()), 13 | HEIF_CHROMA_INTERLEAVED_RRGGBB_BE(heif_h.heif_chroma_interleaved_RRGGBB_BE()), 14 | HEIF_CHROMA_INTERLEAVED_RRGGBBAA_BE(heif_h.heif_chroma_interleaved_RRGGBBAA_BE()), 15 | HEIF_CHROMA_INTERLEAVED_RRGGBB_LE(heif_h.heif_chroma_interleaved_RRGGBB_LE()), 16 | HEIF_CHROMA_INTERLEAVED_RRGGBBAA_LE(heif_h.heif_chroma_interleaved_RRGGBBAA_LE()); 17 | 18 | private final int val; 19 | 20 | HeifChroma(int val) { 21 | this.val = val; 22 | } 23 | 24 | public int intValue() { 25 | return val; 26 | } 27 | 28 | public static HeifChroma fromId(int id) { 29 | for (HeifChroma type : values()) { 30 | if (type.intValue() == id) { 31 | return type; 32 | } 33 | } 34 | return null; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/enums/HeifColorSpace.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.lib.enums; 2 | 3 | import com.github.gotson.nightmonkeys.heif.lib.panama.heif_h; 4 | 5 | public enum HeifColorSpace { 6 | HEIF_COLOR_SPACE_UNDEFINED(heif_h.heif_colorspace_undefined()), 7 | HEIF_COLOR_SPACE_YCBCR(heif_h.heif_colorspace_YCbCr()), 8 | HEIF_COLOR_SPACE_RGB(heif_h.heif_colorspace_RGB()), 9 | HEIF_COLOR_SPACE_MONOCHROME(heif_h.heif_colorspace_monochrome()); 10 | 11 | private final int val; 12 | 13 | HeifColorSpace(int val) { 14 | this.val = val; 15 | } 16 | 17 | public int intValue() { 18 | return val; 19 | } 20 | 21 | public static HeifColorSpace fromId(int id) { 22 | for (HeifColorSpace type : values()) { 23 | if (type.intValue() == id) { 24 | return type; 25 | } 26 | } 27 | return null; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/enums/HeifCompressionFormat.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.lib.enums; 2 | 3 | import com.github.gotson.nightmonkeys.heif.lib.panama.heif_h; 4 | 5 | public enum HeifCompressionFormat { 6 | HEIF_COMPRESSION_UNDEFINED(heif_h.heif_compression_undefined()), 7 | HEIF_COMPRESSION_HEVC(heif_h.heif_compression_HEVC()), 8 | HEIF_COMPRESSION_AVC(heif_h.heif_compression_AVC()), 9 | HEIF_COMPRESSION_JPEG(heif_h.heif_compression_JPEG()), 10 | HEIF_COMPRESSION_AV1(heif_h.heif_compression_AV1()), 11 | HEIF_COMPRESSION_VVC(heif_h.heif_compression_VVC()), 12 | HEIF_COMPRESSION_EVC(heif_h.heif_compression_EVC()), 13 | HEIF_COMPRESSION_JPEG2000(heif_h.heif_compression_JPEG2000()), 14 | HEIF_COMPRESSION_UNCOMPRESSED(heif_h.heif_compression_uncompressed()), 15 | ; 16 | 17 | private final int val; 18 | 19 | HeifCompressionFormat(int val) { 20 | this.val = val; 21 | } 22 | 23 | public int intValue() { 24 | return val; 25 | } 26 | 27 | public static HeifCompressionFormat fromId(int id) { 28 | for (HeifCompressionFormat type : values()) { 29 | if (type.intValue() == id) { 30 | return type; 31 | } 32 | } 33 | return null; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/enums/HeifErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.lib.enums; 2 | 3 | import com.github.gotson.nightmonkeys.heif.lib.panama.heif_h; 4 | 5 | public enum HeifErrorCode { 6 | HEIF_ERROR_OK(heif_h.heif_error_Ok()), 7 | HEIF_ERROR_INPUT_DOES_NOT_EXIST(heif_h.heif_error_Input_does_not_exist()), 8 | HEIF_ERROR_INVALID_INPUT(heif_h.heif_error_Invalid_input()), 9 | HEIF_ERROR_UNSUPPORTED_FILETYPE(heif_h.heif_error_Unsupported_filetype()), 10 | HEIF_ERROR_UNSUPPORTED_FEATURE(heif_h.heif_error_Unsupported_feature()), 11 | HEIF_ERROR_USAGE_ERROR(heif_h.heif_error_Usage_error()), 12 | HEIF_ERROR_MEMORY_ALLOCATION_ERROR(heif_h.heif_error_Memory_allocation_error()), 13 | HEIF_ERROR_DECODER_PLUGIN_ERROR(heif_h.heif_error_Decoder_plugin_error()); 14 | 15 | private final int val; 16 | 17 | HeifErrorCode(int val) { 18 | this.val = val; 19 | } 20 | 21 | public int intValue() { 22 | return val; 23 | } 24 | 25 | public static HeifErrorCode fromId(int id) { 26 | for (HeifErrorCode type : values()) { 27 | if (type.intValue() == id) { 28 | return type; 29 | } 30 | } 31 | return null; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/enums/HeifFiletypeResult.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.lib.enums; 2 | 3 | import com.github.gotson.nightmonkeys.heif.lib.panama.heif_h; 4 | 5 | 6 | public enum HeifFiletypeResult { 7 | HEIF_FILETYPE_NO(heif_h.heif_filetype_no()), 8 | HEIF_FILETYPE_YES_SUPPORTED(heif_h.heif_filetype_yes_supported()), 9 | HEIF_FILETYPE_YES_UNSUPPORTED(heif_h.heif_filetype_yes_unsupported()), 10 | HEIF_FILETYPE_MAYBE(heif_h.heif_filetype_maybe()); 11 | 12 | private final int val; 13 | 14 | HeifFiletypeResult(int val) { 15 | this.val = val; 16 | } 17 | 18 | public int intValue() { 19 | return val; 20 | } 21 | 22 | public static HeifFiletypeResult fromId(int id) { 23 | for (HeifFiletypeResult type : values()) { 24 | if (type.intValue() == id) { 25 | return type; 26 | } 27 | } 28 | return null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/panama/__darwin_mbstate_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.heif.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef __mbstate_t __darwin_mbstate_t 18 | * } 19 | */ 20 | public class __darwin_mbstate_t extends __mbstate_t { 21 | 22 | __darwin_mbstate_t() { 23 | // Should not be called directly 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/panama/__darwin_pthread_attr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.heif.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_attr_t { 18 | * long __sig; 19 | * char __opaque[56]; 20 | * } __darwin_pthread_attr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_attr_t extends _opaque_pthread_attr_t { 24 | 25 | __darwin_pthread_attr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/panama/__darwin_pthread_cond_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.heif.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_cond_t { 18 | * long __sig; 19 | * char __opaque[40]; 20 | * } __darwin_pthread_cond_t 21 | * } 22 | */ 23 | public class __darwin_pthread_cond_t extends _opaque_pthread_cond_t { 24 | 25 | __darwin_pthread_cond_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/panama/__darwin_pthread_condattr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.heif.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_condattr_t { 18 | * long __sig; 19 | * char __opaque[8]; 20 | * } __darwin_pthread_condattr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_condattr_t extends _opaque_pthread_condattr_t { 24 | 25 | __darwin_pthread_condattr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/panama/__darwin_pthread_mutex_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.heif.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_mutex_t { 18 | * long __sig; 19 | * char __opaque[56]; 20 | * } __darwin_pthread_mutex_t 21 | * } 22 | */ 23 | public class __darwin_pthread_mutex_t extends _opaque_pthread_mutex_t { 24 | 25 | __darwin_pthread_mutex_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/panama/__darwin_pthread_mutexattr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.heif.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_mutexattr_t { 18 | * long __sig; 19 | * char __opaque[8]; 20 | * } __darwin_pthread_mutexattr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_mutexattr_t extends _opaque_pthread_mutexattr_t { 24 | 25 | __darwin_pthread_mutexattr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/panama/__darwin_pthread_once_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.heif.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_once_t { 18 | * long __sig; 19 | * char __opaque[8]; 20 | * } __darwin_pthread_once_t 21 | * } 22 | */ 23 | public class __darwin_pthread_once_t extends _opaque_pthread_once_t { 24 | 25 | __darwin_pthread_once_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/panama/__darwin_pthread_rwlock_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.heif.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_rwlock_t { 18 | * long __sig; 19 | * char __opaque[192]; 20 | * } __darwin_pthread_rwlock_t 21 | * } 22 | */ 23 | public class __darwin_pthread_rwlock_t extends _opaque_pthread_rwlock_t { 24 | 25 | __darwin_pthread_rwlock_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/panama/__darwin_pthread_rwlockattr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.heif.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_rwlockattr_t { 18 | * long __sig; 19 | * char __opaque[16]; 20 | * } __darwin_pthread_rwlockattr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_rwlockattr_t extends _opaque_pthread_rwlockattr_t { 24 | 25 | __darwin_pthread_rwlockattr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-heif/src/main/java22/com/github/gotson/nightmonkeys/heif/lib/panama/heif_init_params.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.heif.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * struct heif_init_params { 18 | * int version; 19 | * } 20 | * } 21 | */ 22 | public class heif_init_params { 23 | 24 | heif_init_params() { 25 | // Should not be called directly 26 | } 27 | 28 | private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( 29 | heif_h.C_INT.withName("version") 30 | ).withName("heif_init_params"); 31 | 32 | /** 33 | * The layout of this struct 34 | */ 35 | public static final GroupLayout layout() { 36 | return $LAYOUT; 37 | } 38 | 39 | private static final OfInt version$LAYOUT = (OfInt)$LAYOUT.select(groupElement("version")); 40 | 41 | /** 42 | * Layout for field: 43 | * {@snippet lang=c : 44 | * int version 45 | * } 46 | */ 47 | public static final OfInt version$layout() { 48 | return version$LAYOUT; 49 | } 50 | 51 | private static final long version$OFFSET = 0; 52 | 53 | /** 54 | * Offset for field: 55 | * {@snippet lang=c : 56 | * int version 57 | * } 58 | */ 59 | public static final long version$offset() { 60 | return version$OFFSET; 61 | } 62 | 63 | /** 64 | * Getter for field: 65 | * {@snippet lang=c : 66 | * int version 67 | * } 68 | */ 69 | public static int version(MemorySegment struct) { 70 | return struct.get(version$LAYOUT, version$OFFSET); 71 | } 72 | 73 | /** 74 | * Setter for field: 75 | * {@snippet lang=c : 76 | * int version 77 | * } 78 | */ 79 | public static void version(MemorySegment struct, int fieldValue) { 80 | struct.set(version$LAYOUT, version$OFFSET, fieldValue); 81 | } 82 | 83 | /** 84 | * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. 85 | * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} 86 | */ 87 | public static MemorySegment asSlice(MemorySegment array, long index) { 88 | return array.asSlice(layout().byteSize() * index); 89 | } 90 | 91 | /** 92 | * The size (in bytes) of this struct 93 | */ 94 | public static long sizeof() { return layout().byteSize(); } 95 | 96 | /** 97 | * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} 98 | */ 99 | public static MemorySegment allocate(SegmentAllocator allocator) { 100 | return allocator.allocate(layout()); 101 | } 102 | 103 | /** 104 | * Allocate an array of size {@code elementCount} using {@code allocator}. 105 | * The returned segment has size {@code elementCount * layout().byteSize()}. 106 | */ 107 | public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { 108 | return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); 109 | } 110 | 111 | /** 112 | * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). 113 | * The returned segment has size {@code layout().byteSize()} 114 | */ 115 | public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { 116 | return reinterpret(addr, 1, arena, cleanup); 117 | } 118 | 119 | /** 120 | * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). 121 | * The returned segment has size {@code elementCount * layout().byteSize()} 122 | */ 123 | public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { 124 | return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); 125 | } 126 | } 127 | 128 | -------------------------------------------------------------------------------- /imageio-heif/src/main/resources/META-INF/services/javax.imageio.spi.ImageReaderSpi: -------------------------------------------------------------------------------- 1 | com.github.gotson.nightmonkeys.heif.imageio.plugins.HeifImageReaderSpi -------------------------------------------------------------------------------- /imageio-heif/src/main/resources/META-INF/services/javax.imageio.spi.ImageWriterSpi: -------------------------------------------------------------------------------- 1 | com.github.gotson.nightmonkeys.heif.imageio.plugins.HeifImageWriterSpi -------------------------------------------------------------------------------- /imageio-heif/src/test/java/com/github/gotson/nightmonkeys/heif/imageio/plugins/HeifImageReaderTest.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.NoOpImageReaderAbstractTest; 4 | import com.github.gotson.nightmonkeys.common.imageio.ProviderInfo; 5 | 6 | class HeifImageReaderTest extends NoOpImageReaderAbstractTest { 7 | @Override 8 | protected ProviderInfo createProvider() { 9 | return new HeifProviderInfo(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /imageio-heif/src/test/java/com/github/gotson/nightmonkeys/heif/imageio/plugins/HeifImageWriterTest.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.NoOpImageWriterAbstractTest; 4 | import com.github.gotson.nightmonkeys.common.imageio.ProviderInfo; 5 | 6 | class HeifImageWriterTest extends NoOpImageWriterAbstractTest { 7 | @Override 8 | protected ProviderInfo createProvider() { 9 | return new HeifProviderInfo(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /imageio-heif/src/test/java22/com/github/gotson/nightmonkeys/heif/imageio/plugins/HeifImageReaderTest.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.ImageReaderAbstractTest; 4 | 5 | import javax.imageio.spi.ImageReaderSpi; 6 | import java.awt.Dimension; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | import static java.util.Arrays.asList; 11 | 12 | public class HeifImageReaderTest extends ImageReaderAbstractTest { 13 | 14 | @Override 15 | protected ImageReaderSpi createProvider() { 16 | return new HeifImageReaderSpi(); 17 | } 18 | 19 | @Override 20 | protected List getTestData() { 21 | return asList( 22 | // HEIF (from http://nokiatech.github.io/heif/examples.html) 23 | // Each file contains a high quality still image and its thumbnail 24 | new TestData(getClassLoaderResource("/heif/autumn_1440x960.heic"), new Dimension(1440, 960)), 25 | new TestData(getClassLoaderResource("/heif/old_bridge_1440x960.heic"), new Dimension(1440, 960)), 26 | 27 | // HEIF (from https://www.dwsamplefiles.com/download-heif-sample-files/) 28 | new TestData(getClassLoaderResource("/heif/dwsample-heif-640.heif"), new Dimension(640, 427)), 29 | 30 | // HEIF (from https://github.com/nokiatech/heif_conformance) 31 | // An image item with an associated alpha mask auxiliary image 32 | new TestData(getClassLoaderResource("/heif/C006.heic"), new Dimension(1280, 720)), 33 | 34 | // HEIC Collection (from http://nokiatech.github.io/heif/examples.html) 35 | new TestData(getClassLoaderResource("/heif/collection_random_1440x960.heic"), Collections.nCopies(4, new Dimension(1440, 960)), null), 36 | new TestData(getClassLoaderResource("/heif/collection_season_1440x960.heic"), Collections.nCopies(4, new Dimension(1440, 960)), null), 37 | 38 | // HEIC Image Bursts 39 | // Each file contains a short video, thumbnails of each frame in the video and high quality version of the “selected best shots” from an image burst. 40 | // The files are represented in two different modes: 1. Burst images, 2. Video and HD quality images. 41 | // Status: 4 images available 42 | new TestData(getClassLoaderResource("/heif/burst_bird.heic"), Collections.nCopies(4, new Dimension(1280, 720)), null), 43 | new TestData(getClassLoaderResource("/heif/burst_rally.heic"), Collections.nCopies(4, new Dimension(1280, 720)), null), 44 | 45 | // HEIC Animation (from http://nokiatech.github.io/heif/examples.html) 46 | // Each file contains multiple still images, just like an album or collection. Album groupings and descriptions can be indicated in the file: 47 | // Status: not supported by libheif, only 1 image will be available 48 | new TestData(getClassLoaderResource("/heif/animation_sea1.heic"), new Dimension(256, 144)), 49 | new TestData(getClassLoaderResource("/heif/animation_starfield.heic"), new Dimension(256, 144)), 50 | 51 | // AVIF (from http://188.121.162.14/avif/) 52 | new TestData(getClassLoaderResource("/avif/avif-enabled.avif"), new Dimension(640, 478)), 53 | 54 | // AVIF Animation (from http://188.121.162.14/avif/) 55 | // Status: not supported by libheif, only 1 image will be available 56 | new TestData(getClassLoaderResource("/avif/animation2.avif"), new Dimension(640, 640)), 57 | 58 | // AVIF with stride != from width 59 | new TestData(getClassLoaderResource("/avif/kk.avif"), new Dimension(2535, 4167)), 60 | new TestData(getClassLoaderResource("/avif/monster.avif"), new Dimension(846, 1200)) 61 | ); 62 | } 63 | 64 | @Override 65 | protected List getFormatNames() { 66 | return List.of(new HeifProviderInfo().getFormatNames()); 67 | } 68 | 69 | @Override 70 | protected List getSuffixes() { 71 | return List.of(new HeifProviderInfo().getSuffixes()); 72 | } 73 | 74 | @Override 75 | protected List getMIMETypes() { 76 | return List.of(new HeifProviderInfo().getMimeTypes()); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /imageio-heif/src/test/java22/com/github/gotson/nightmonkeys/heif/imageio/plugins/HeifImageWriterTest.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.heif.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.ImageWriterAbstractTest; 4 | import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers; 5 | 6 | import javax.imageio.ImageWriteParam; 7 | import javax.imageio.ImageWriter; 8 | import javax.imageio.spi.ImageWriterSpi; 9 | import java.awt.color.ColorSpace; 10 | import java.awt.image.BufferedImage; 11 | import java.awt.image.DataBuffer; 12 | import java.awt.image.RenderedImage; 13 | import java.io.IOException; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | public class HeifImageWriterTest extends ImageWriterAbstractTest { 18 | @Override 19 | protected ImageWriterSpi createProvider() { 20 | return new HeifImageWriterSpi(); 21 | } 22 | 23 | @Override 24 | protected String getTestFileExtension() { 25 | return "heif"; 26 | } 27 | 28 | @Override 29 | protected List getTestData() { 30 | return List.of( 31 | new BufferedImage(1024, 1024, BufferedImage.TYPE_INT_ARGB), 32 | new BufferedImage(1024, 1024, BufferedImage.TYPE_INT_BGR), 33 | new BufferedImage(1024, 1024, BufferedImage.TYPE_INT_RGB), 34 | new BufferedImage(1024, 1024, BufferedImage.TYPE_INT_ARGB_PRE), 35 | // this image has different masks (RGBA) from the defaults (ARGB) 36 | ImageTypeSpecifiers.createPacked(ColorSpace.getInstance(ColorSpace.CS_sRGB), 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, DataBuffer.TYPE_INT, false) 37 | .createBufferedImage(512, 1024) 38 | ); 39 | } 40 | 41 | @Override 42 | protected List getTestWriteParams() { 43 | List params = new ArrayList<>(); 44 | ImageWriter writer; 45 | try { 46 | writer = createWriter(); 47 | } catch (IOException e) { 48 | throw new RuntimeException(e); 49 | } 50 | 51 | for (String compressionType : writer.getDefaultWriteParam().getCompressionTypes()) { 52 | for (int i = 0; i <= 10; i++) { 53 | HeifWriteParam param = (HeifWriteParam) writer.getDefaultWriteParam(); 54 | param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 55 | param.setCompressionType(compressionType); 56 | param.setLossless(i == 0); 57 | if (i > 0) param.setCompressionQuality(i * 0.1F); 58 | params.add(param); 59 | } 60 | } 61 | return params; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /imageio-heif/src/test/resources/avif/animation2.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-heif/src/test/resources/avif/animation2.avif -------------------------------------------------------------------------------- /imageio-heif/src/test/resources/avif/avif-enabled.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-heif/src/test/resources/avif/avif-enabled.avif -------------------------------------------------------------------------------- /imageio-heif/src/test/resources/avif/kk.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-heif/src/test/resources/avif/kk.avif -------------------------------------------------------------------------------- /imageio-heif/src/test/resources/avif/monster.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-heif/src/test/resources/avif/monster.avif -------------------------------------------------------------------------------- /imageio-heif/src/test/resources/heif/C006.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-heif/src/test/resources/heif/C006.heic -------------------------------------------------------------------------------- /imageio-heif/src/test/resources/heif/animation_sea1.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-heif/src/test/resources/heif/animation_sea1.heic -------------------------------------------------------------------------------- /imageio-heif/src/test/resources/heif/animation_starfield.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-heif/src/test/resources/heif/animation_starfield.heic -------------------------------------------------------------------------------- /imageio-heif/src/test/resources/heif/autumn_1440x960.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-heif/src/test/resources/heif/autumn_1440x960.heic -------------------------------------------------------------------------------- /imageio-heif/src/test/resources/heif/burst_bird.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-heif/src/test/resources/heif/burst_bird.heic -------------------------------------------------------------------------------- /imageio-heif/src/test/resources/heif/burst_rally.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-heif/src/test/resources/heif/burst_rally.heic -------------------------------------------------------------------------------- /imageio-heif/src/test/resources/heif/collection_random_1440x960.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-heif/src/test/resources/heif/collection_random_1440x960.heic -------------------------------------------------------------------------------- /imageio-heif/src/test/resources/heif/collection_season_1440x960.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-heif/src/test/resources/heif/collection_season_1440x960.heic -------------------------------------------------------------------------------- /imageio-heif/src/test/resources/heif/dwsample-heif-640.heif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-heif/src/test/resources/heif/dwsample-heif-640.heif -------------------------------------------------------------------------------- /imageio-heif/src/test/resources/heif/old_bridge_1440x960.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-heif/src/test/resources/heif/old_bridge_1440x960.heic -------------------------------------------------------------------------------- /imageio-jxl/README.md: -------------------------------------------------------------------------------- 1 | # ImageIO Jpeg XL plugin 2 | 3 | ## Requirements 4 | 5 | `libjxl` version 0.6.1+ must be installed on the target system. 6 | 7 | ## Known installations methods 8 | 9 | - Homebrew (Mac & Linux): `brew install jpeg-xl` 10 | - apt (Linux): `apt-get install libjxl-dev` 11 | 12 | ## Features 13 | 14 | - Decode Jpeg XL images 15 | 16 | ## Limitations 17 | 18 | - Animations are not supported. A single image is returned. 19 | 20 | ## Implementation notes 21 | 22 | The `panama` package bindings were generated using: 23 | - jextract 22 24 | - from the https://github.com/libjxl/libjxl repository, version 0.6.1 25 | - based on the `decode.h` header file 26 | 27 | The bindings were slightly adjusted for `JxlDecoderGetICCProfileSize` and `JxlDecoderGetColorAsICCProfile`, following a breaking change in [v0.9.0](https://github.com/libjxl/libjxl/releases/tag/v0.9.0) where a deprecated unused argument was removed. -------------------------------------------------------------------------------- /imageio-jxl/build.gradle: -------------------------------------------------------------------------------- 1 | description = 'NightMonkeys :: ImageIO :: JPEG XL plugin' 2 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java/com/github/gotson/nightmonkeys/jxl/imageio/plugins/JxlImageReader.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.jxl.imageio.plugins; 2 | 3 | import javax.imageio.ImageReadParam; 4 | import javax.imageio.ImageReader; 5 | import javax.imageio.ImageTypeSpecifier; 6 | import javax.imageio.metadata.IIOMetadata; 7 | import javax.imageio.spi.ImageReaderSpi; 8 | import java.awt.image.BufferedImage; 9 | import java.io.IOException; 10 | import java.util.Iterator; 11 | 12 | public class JxlImageReader extends ImageReader { 13 | 14 | protected JxlImageReader(ImageReaderSpi originatingProvider) { 15 | super(originatingProvider); 16 | } 17 | 18 | /** 19 | * The number of images corresponds to the number of different resolutions that can be directly 20 | * decoded. 21 | */ 22 | @Override 23 | public int getNumImages(boolean allowSearch) { 24 | return 0; 25 | } 26 | 27 | @Override 28 | public int getWidth(int imageIndex) throws IOException { 29 | throw new IOException(); 30 | } 31 | 32 | @Override 33 | public int getHeight(int imageIndex) throws IOException { 34 | throw new IOException(); 35 | } 36 | 37 | @Override 38 | public Iterator getImageTypes(int imageIndex) throws IOException { 39 | throw new IOException(); 40 | } 41 | 42 | @Override 43 | public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException { 44 | throw new IOException(); 45 | } 46 | 47 | @Override 48 | public IIOMetadata getStreamMetadata() { 49 | return null; 50 | } 51 | 52 | @Override 53 | public IIOMetadata getImageMetadata(int imageIndex) { 54 | return null; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java/com/github/gotson/nightmonkeys/jxl/imageio/plugins/JxlImageReaderSpi.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.jxl.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.ImageReaderSpiBase; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import javax.imageio.ImageReader; 8 | import javax.imageio.spi.ServiceRegistry; 9 | import java.util.Locale; 10 | 11 | public class JxlImageReaderSpi extends ImageReaderSpiBase { 12 | 13 | private static final Logger LOGGER = LoggerFactory.getLogger(JxlImageReaderSpi.class); 14 | 15 | public JxlImageReaderSpi() { 16 | super(new JxlProviderInfo()); 17 | } 18 | 19 | @Override 20 | public void onRegistration(ServiceRegistry registry, Class category) { 21 | LOGGER.info("This plugin only supports Java 22, plugin will be disabled"); 22 | registry.deregisterServiceProvider(this); 23 | super.onRegistration(registry, category); 24 | } 25 | 26 | @Override 27 | public boolean canDecodeInput(Object input) { 28 | return false; 29 | } 30 | 31 | @Override 32 | public ImageReader createReaderInstance(Object extension) { 33 | return new JxlImageReader(this); 34 | } 35 | 36 | @Override 37 | public String getDescription(Locale locale) { 38 | return "Jpeg XL reader plugin based on libjxl."; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java/com/github/gotson/nightmonkeys/jxl/imageio/plugins/JxlProviderInfo.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.jxl.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.ProviderInfo; 4 | 5 | final class JxlProviderInfo extends ProviderInfo { 6 | JxlProviderInfo() { 7 | super( 8 | new String[] {"Jpeg XL", "jxl"}, 9 | new String[] {"jxl"}, 10 | new String[] {"image/jxl"}, 11 | "com.github.gotson.nightmonkeys.jxl.imageio.JxlImageReader", 12 | new String[] { "com.github.gotson.nightmonkeys.jxl.imageio.JxlImageReaderSpi"}, 13 | null, 14 | null, 15 | false, 16 | null, 17 | null, 18 | null, 19 | null, 20 | false, 21 | null, 22 | null, 23 | null, 24 | null 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/BasicInfo.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.jxl; 2 | 3 | import java.awt.color.ICC_Profile; 4 | 5 | public record BasicInfo( 6 | int width, 7 | int height, 8 | boolean hasAlpha, 9 | boolean hasAnimation, 10 | int colorChannels, 11 | ICC_Profile iccProfile, 12 | int frameCount) { 13 | } 14 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/JxlException.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.jxl; 2 | 3 | public class JxlException extends Exception { 4 | public JxlException(String message) { 5 | super(message); 6 | } 7 | 8 | public JxlException(String message, Throwable cause) { 9 | super(message, cause); 10 | } 11 | 12 | public JxlException(Throwable e) { 13 | super(e); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/imageio/plugins/JxlImageReader.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.jxl.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.jxl.BasicInfo; 4 | import com.github.gotson.nightmonkeys.jxl.JpegXl; 5 | import com.github.gotson.nightmonkeys.jxl.JxlException; 6 | import com.twelvemonkeys.imageio.ImageReaderBase; 7 | import com.twelvemonkeys.imageio.color.ColorSpaces; 8 | import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import javax.imageio.ImageReadParam; 13 | import javax.imageio.ImageTypeSpecifier; 14 | import javax.imageio.metadata.IIOMetadata; 15 | import javax.imageio.spi.ImageReaderSpi; 16 | import javax.imageio.stream.ImageInputStream; 17 | import java.awt.color.ColorSpace; 18 | import java.awt.image.BufferedImage; 19 | import java.awt.image.DataBuffer; 20 | import java.io.IOException; 21 | import java.util.Iterator; 22 | import java.util.List; 23 | 24 | public class JxlImageReader extends ImageReaderBase { 25 | 26 | private static final Logger LOGGER = LoggerFactory.getLogger(JxlImageReader.class); 27 | 28 | private BasicInfo info; 29 | 30 | private List imageTypes; 31 | 32 | protected JxlImageReader(ImageReaderSpi originatingProvider) { 33 | super(originatingProvider); 34 | } 35 | 36 | private void readInfo() throws IOException { 37 | if (info == null) { 38 | 39 | try { 40 | info = JpegXl.getBasicInfo((ImageInputStream) input); 41 | 42 | ColorSpace colorSpace = ColorSpaces.createColorSpace(info.iccProfile()); 43 | if (colorSpace == null || colorSpace.getType() != ColorSpace.TYPE_RGB) colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB); 44 | imageTypes = List.of( 45 | // RGBA 46 | ImageTypeSpecifiers.createPacked(colorSpace, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, DataBuffer.TYPE_INT, false) 47 | ); 48 | } catch (JxlException e) { 49 | throw new IOException(e); 50 | } 51 | } 52 | } 53 | 54 | private void readInfo(int imageIndex) throws IOException { 55 | checkBounds(imageIndex); 56 | 57 | readInfo(); 58 | } 59 | 60 | /** 61 | * The number of images corresponds to the number of different resolutions that can be directly 62 | * decoded. 63 | */ 64 | @Override 65 | public int getNumImages(boolean allowSearch) throws IOException { 66 | assertInput(); 67 | readInfo(); 68 | 69 | return info.frameCount(); 70 | } 71 | 72 | @Override 73 | public int getWidth(int imageIndex) throws IOException { 74 | readInfo(imageIndex); 75 | 76 | return info.width(); 77 | } 78 | 79 | @Override 80 | public int getHeight(int imageIndex) throws IOException { 81 | readInfo(imageIndex); 82 | 83 | return info.height(); 84 | } 85 | 86 | @Override 87 | public ImageTypeSpecifier getRawImageType(int imageIndex) throws IOException { 88 | readInfo(imageIndex); 89 | 90 | return imageTypes.get(0); 91 | } 92 | 93 | @Override 94 | public Iterator getImageTypes(int imageIndex) throws IOException { 95 | readInfo(imageIndex); 96 | 97 | return imageTypes.iterator(); 98 | } 99 | 100 | @Override 101 | public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException { 102 | readInfo(imageIndex); 103 | 104 | int width = getWidth(imageIndex); 105 | int height = getHeight(imageIndex); 106 | BufferedImage destination = getDestination(param, getImageTypes(imageIndex), width, height); 107 | 108 | processImageStarted(imageIndex); 109 | processImageProgress(0F); 110 | 111 | try { 112 | JpegXl.decode((ImageInputStream) getInput(), info, destination.getRaster(), param, imageIndex); 113 | } catch (JxlException e) { 114 | throw new IOException(e); 115 | } 116 | 117 | if (abortRequested()) { 118 | processReadAborted(); 119 | } else { 120 | processImageComplete(); 121 | } 122 | 123 | return destination; 124 | } 125 | 126 | @Override 127 | public IIOMetadata getStreamMetadata() { 128 | return null; 129 | } 130 | 131 | @Override 132 | public IIOMetadata getImageMetadata(int imageIndex) { 133 | return null; 134 | } 135 | 136 | @Override 137 | public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) { 138 | info = null; 139 | imageTypes = null; 140 | super.setInput(input, seekForwardOnly, ignoreMetadata); 141 | } 142 | 143 | @Override 144 | protected void resetMembers() { 145 | info = null; 146 | imageTypes = null; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/imageio/plugins/JxlImageReaderSpi.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.jxl.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.ImageReaderSpiBase; 4 | import com.github.gotson.nightmonkeys.jxl.JpegXl; 5 | import com.github.gotson.nightmonkeys.jxl.JxlException; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import javax.imageio.ImageIO; 10 | import javax.imageio.ImageReader; 11 | import javax.imageio.spi.ImageReaderSpi; 12 | import javax.imageio.spi.ServiceRegistry; 13 | import javax.imageio.stream.ImageInputStream; 14 | import java.io.IOException; 15 | import java.util.Locale; 16 | 17 | public class JxlImageReaderSpi extends ImageReaderSpiBase { 18 | 19 | private static final Logger LOGGER = LoggerFactory.getLogger(JxlImageReaderSpi.class); 20 | private boolean libLoaded = false; 21 | 22 | public JxlImageReaderSpi() { 23 | super(new JxlProviderInfo()); 24 | } 25 | 26 | private boolean loadLibrary() { 27 | if (!libLoaded) { 28 | try { 29 | String libVersion = JpegXl.getLibVersion(); 30 | LOGGER.info("Loaded libjxl v{}", libVersion); 31 | libLoaded = true; 32 | } catch (UnsatisfiedLinkError e) { 33 | LOGGER.warn("Could not load libjxl, plugin will be disabled. {}", e.getMessage()); 34 | } catch (ExceptionInInitializerError e) { 35 | LOGGER.warn("Native access is disabled, plugin will be disabled. Try adding JVM arguments: --enable-native-access=ALL-UNNAMED"); 36 | } catch (Exception e) { 37 | LOGGER.warn("Unknown error", e); 38 | } 39 | } 40 | return libLoaded; 41 | } 42 | 43 | @Override 44 | public void onRegistration(ServiceRegistry registry, Class category) { 45 | if (!loadLibrary()) { 46 | LOGGER.info("Deregistering service provider"); 47 | registry.deregisterServiceProvider(this); 48 | } 49 | super.onRegistration(registry, category); 50 | } 51 | 52 | @Override 53 | public boolean canDecodeInput(Object input) throws IOException { 54 | if (!(input instanceof ImageInputStream)) { 55 | input = ImageIO.createImageInputStream(input); 56 | } 57 | if (input == null) { 58 | return false; 59 | } 60 | 61 | try { 62 | return JpegXl.canDecode((ImageInputStream) input); 63 | } catch (JxlException e) { 64 | throw new IOException(e); 65 | } 66 | } 67 | 68 | @Override 69 | public ImageReader createReaderInstance(Object extension) { 70 | return new JxlImageReader(this); 71 | } 72 | 73 | @Override 74 | public String getDescription(Locale locale) { 75 | return "Jpeg XL reader plugin based on libjxl."; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/enums/JxlColorProfileTarget.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.jxl.lib.enums; 2 | 3 | import com.github.gotson.nightmonkeys.jxl.lib.panama.decode_h; 4 | 5 | /** 6 | * Defines which color profile to get: the profile from the codestream 7 | * metadata header, which represents the color profile of the original image, 8 | * or the color profile from the pixel data received by the decoder. Both are 9 | * the same if the basic has uses_original_profile set. 10 | */ 11 | public enum JxlColorProfileTarget { 12 | /** 13 | * Get the color profile of the original image from the metadata. 14 | */ 15 | JXL_COLOR_PROFILE_TARGET_ORIGINAL(decode_h.JXL_COLOR_PROFILE_TARGET_ORIGINAL()), 16 | 17 | /** 18 | * Get the color profile of the pixel data the decoder outputs. 19 | */ 20 | JXL_COLOR_PROFILE_TARGET_DATA(decode_h.JXL_COLOR_PROFILE_TARGET_DATA()); 21 | 22 | private final int val; 23 | 24 | JxlColorProfileTarget(int val) { 25 | this.val = val; 26 | } 27 | 28 | public int intValue() { 29 | return val; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/enums/JxlDataType.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.jxl.lib.enums; 2 | 3 | import com.github.gotson.nightmonkeys.jxl.lib.panama.decode_h; 4 | 5 | /** 6 | * Data type for the sample values per channel per pixel. 7 | */ 8 | public enum JxlDataType { 9 | /** 10 | * Use 32-bit single-precision floating point values, with range 0.0-1.0 11 | * (within gamut, may go outside this range for wide color gamut). Floating 12 | * point output, either JXL_TYPE_FLOAT or JXL_TYPE_FLOAT16, is recommended 13 | * for HDR and wide gamut images when color profile conversion is required. 14 | */ 15 | JXL_TYPE_FLOAT(decode_h.JXL_TYPE_FLOAT()), 16 | 17 | /** 18 | * Use 1-bit packed in uint8_t, first pixel in LSB, padded to uint8_t per 19 | * row. 20 | */ 21 | JXL_TYPE_BOOLEAN(decode_h.JXL_TYPE_BOOLEAN()), 22 | 23 | /** 24 | * Use type uint8_t. May clip wide color gamut data. 25 | */ 26 | JXL_TYPE_UINT8(decode_h.JXL_TYPE_UINT8()), 27 | 28 | /** 29 | * Use type uint16_t. May clip wide color gamut data. 30 | */ 31 | JXL_TYPE_UINT16(decode_h.JXL_TYPE_UINT16()), 32 | 33 | /** 34 | * Use type uint32_t. May clip wide color gamut data. 35 | */ 36 | JXL_TYPE_UINT32(decode_h.JXL_TYPE_UINT32()), 37 | 38 | /** 39 | * Use 16-bit IEEE 754 half-precision floating point values 40 | */ 41 | JXL_TYPE_FLOAT16(decode_h.JXL_TYPE_FLOAT16()); 42 | 43 | private final int val; 44 | 45 | JxlDataType(int val) { 46 | this.val = val; 47 | } 48 | 49 | public int intValue() { 50 | return val; 51 | } 52 | 53 | public int sizeBytes() { 54 | return switch (this) { 55 | case JXL_TYPE_FLOAT, JXL_TYPE_UINT32 -> 4; 56 | case JXL_TYPE_BOOLEAN, JXL_TYPE_UINT8 -> 1; 57 | case JXL_TYPE_UINT16, JXL_TYPE_FLOAT16 -> 2; 58 | }; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/enums/JxlEndianness.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.jxl.lib.enums; 2 | 3 | import com.github.gotson.nightmonkeys.jxl.lib.panama.decode_h; 4 | 5 | /** 6 | * Ordering of multi-byte data. 7 | */ 8 | public enum JxlEndianness { 9 | /** 10 | * Use the endianness of the system, either little endian or big endian, 11 | * without forcing either specific endianness. Do not use if pixel data 12 | * should be exported to a well defined format. 13 | */ 14 | JXL_NATIVE_ENDIAN(decode_h.JXL_NATIVE_ENDIAN()), 15 | 16 | /** 17 | * Force little endian 18 | */ 19 | JXL_LITTLE_ENDIAN(decode_h.JXL_LITTLE_ENDIAN()), 20 | 21 | /** 22 | * Force big endian 23 | */ 24 | JXL_BIG_ENDIAN(decode_h.JXL_BIG_ENDIAN()); 25 | 26 | private final int val; 27 | 28 | JxlEndianness(int val) { 29 | this.val = val; 30 | } 31 | 32 | public int intValue() { 33 | return val; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/enums/JxlOrientation.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.jxl.lib.enums; 2 | 3 | import com.github.gotson.nightmonkeys.jxl.lib.panama.decode_h; 4 | 5 | /** 6 | * Image orientation metadata. 7 | * Values 1..8 match the EXIF definitions. 8 | * The name indicates the operation to perform to transform from the encoded 9 | * image to the display image. 10 | */ 11 | public enum JxlOrientation { 12 | JXL_ORIENT_IDENTITY(decode_h.JXL_ORIENT_IDENTITY()), 13 | JXL_ORIENT_FLIP_HORIZONTAL(decode_h.JXL_ORIENT_FLIP_HORIZONTAL()), 14 | JXL_ORIENT_ROTATE_180(decode_h.JXL_ORIENT_ROTATE_180()), 15 | JXL_ORIENT_FLIP_VERTICAL(decode_h.JXL_ORIENT_FLIP_VERTICAL()), 16 | JXL_ORIENT_TRANSPOSE(decode_h.JXL_ORIENT_TRANSPOSE()), 17 | JXL_ORIENT_ROTATE_90_CW(decode_h.JXL_ORIENT_ROTATE_90_CW()), 18 | JXL_ORIENT_ANTI_TRANSPOSE(decode_h.JXL_ORIENT_ANTI_TRANSPOSE()), 19 | JXL_ORIENT_ROTATE_90_CCW(decode_h.JXL_ORIENT_ROTATE_90_CCW()); 20 | 21 | private final int val; 22 | 23 | JxlOrientation(int val) { 24 | this.val = val; 25 | } 26 | 27 | public int intValue() { 28 | return val; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/enums/JxlSignature.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.jxl.lib.enums; 2 | 3 | import com.github.gotson.nightmonkeys.jxl.lib.panama.decode_h; 4 | 5 | /** 6 | * The result of JxlSignatureCheck. 7 | */ 8 | public enum JxlSignature { 9 | /** 10 | * Not enough bytes were passed to determine if a valid signature was found. 11 | */ 12 | JXL_SIG_NOT_ENOUGH_BYTES(decode_h.JXL_SIG_NOT_ENOUGH_BYTES()), 13 | /** 14 | * No valid JPEGXL header was found. 15 | */ 16 | JXL_SIG_INVALID(decode_h.JXL_SIG_INVALID()), 17 | /** 18 | * A valid JPEG XL codestream signature was found, that is a JPEG XL image 19 | * without container. 20 | */ 21 | JXL_SIG_CODESTREAM(decode_h.JXL_SIG_CODESTREAM()), 22 | /** 23 | * A valid container signature was found, that is a JPEG XL image embedded 24 | * in a box format container. 25 | */ 26 | JXL_SIG_CONTAINER(decode_h.JXL_SIG_CONTAINER()); 27 | 28 | private final int val; 29 | 30 | JxlSignature(int val) { 31 | this.val = val; 32 | } 33 | 34 | public int intValue() { 35 | return val; 36 | } 37 | 38 | public static JxlSignature fromId(int id) { 39 | for (JxlSignature type : values()) { 40 | if (type.intValue() == id) { 41 | return type; 42 | } 43 | } 44 | return null; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/JxlHeaderExtensions.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * struct { 18 | * uint64_t extensions; 19 | * } 20 | * } 21 | */ 22 | public class JxlHeaderExtensions { 23 | 24 | JxlHeaderExtensions() { 25 | // Should not be called directly 26 | } 27 | 28 | private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( 29 | decode_h.C_LONG_LONG.withName("extensions") 30 | ).withName("$anon$285:9"); 31 | 32 | /** 33 | * The layout of this struct 34 | */ 35 | public static final GroupLayout layout() { 36 | return $LAYOUT; 37 | } 38 | 39 | private static final OfLong extensions$LAYOUT = (OfLong)$LAYOUT.select(groupElement("extensions")); 40 | 41 | /** 42 | * Layout for field: 43 | * {@snippet lang=c : 44 | * uint64_t extensions 45 | * } 46 | */ 47 | public static final OfLong extensions$layout() { 48 | return extensions$LAYOUT; 49 | } 50 | 51 | private static final long extensions$OFFSET = 0; 52 | 53 | /** 54 | * Offset for field: 55 | * {@snippet lang=c : 56 | * uint64_t extensions 57 | * } 58 | */ 59 | public static final long extensions$offset() { 60 | return extensions$OFFSET; 61 | } 62 | 63 | /** 64 | * Getter for field: 65 | * {@snippet lang=c : 66 | * uint64_t extensions 67 | * } 68 | */ 69 | public static long extensions(MemorySegment struct) { 70 | return struct.get(extensions$LAYOUT, extensions$OFFSET); 71 | } 72 | 73 | /** 74 | * Setter for field: 75 | * {@snippet lang=c : 76 | * uint64_t extensions 77 | * } 78 | */ 79 | public static void extensions(MemorySegment struct, long fieldValue) { 80 | struct.set(extensions$LAYOUT, extensions$OFFSET, fieldValue); 81 | } 82 | 83 | /** 84 | * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. 85 | * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} 86 | */ 87 | public static MemorySegment asSlice(MemorySegment array, long index) { 88 | return array.asSlice(layout().byteSize() * index); 89 | } 90 | 91 | /** 92 | * The size (in bytes) of this struct 93 | */ 94 | public static long sizeof() { return layout().byteSize(); } 95 | 96 | /** 97 | * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} 98 | */ 99 | public static MemorySegment allocate(SegmentAllocator allocator) { 100 | return allocator.allocate(layout()); 101 | } 102 | 103 | /** 104 | * Allocate an array of size {@code elementCount} using {@code allocator}. 105 | * The returned segment has size {@code elementCount * layout().byteSize()}. 106 | */ 107 | public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { 108 | return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); 109 | } 110 | 111 | /** 112 | * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). 113 | * The returned segment has size {@code layout().byteSize()} 114 | */ 115 | public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { 116 | return reinterpret(addr, 1, arena, cleanup); 117 | } 118 | 119 | /** 120 | * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). 121 | * The returned segment has size {@code elementCount * layout().byteSize()} 122 | */ 123 | public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { 124 | return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); 125 | } 126 | } 127 | 128 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/JxlImageOutCallback.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef void (*JxlImageOutCallback)(void *, size_t, size_t, size_t, const void *) 18 | * } 19 | */ 20 | public class JxlImageOutCallback { 21 | 22 | JxlImageOutCallback() { 23 | // Should not be called directly 24 | } 25 | 26 | /** 27 | * The function pointer signature, expressed as a functional interface 28 | */ 29 | public interface Function { 30 | void apply(MemorySegment opaque, long x, long y, long num_pixels, MemorySegment pixels); 31 | } 32 | 33 | private static final FunctionDescriptor $DESC = FunctionDescriptor.ofVoid( 34 | decode_h.C_POINTER, 35 | decode_h.C_LONG, 36 | decode_h.C_LONG, 37 | decode_h.C_LONG, 38 | decode_h.C_POINTER 39 | ); 40 | 41 | /** 42 | * The descriptor of this function pointer 43 | */ 44 | public static FunctionDescriptor descriptor() { 45 | return $DESC; 46 | } 47 | 48 | private static final MethodHandle UP$MH = decode_h.upcallHandle(JxlImageOutCallback.Function.class, "apply", $DESC); 49 | 50 | /** 51 | * Allocates a new upcall stub, whose implementation is defined by {@code fi}. 52 | * The lifetime of the returned segment is managed by {@code arena} 53 | */ 54 | public static MemorySegment allocate(JxlImageOutCallback.Function fi, Arena arena) { 55 | return Linker.nativeLinker().upcallStub(UP$MH.bindTo(fi), $DESC, arena); 56 | } 57 | 58 | private static final MethodHandle DOWN$MH = Linker.nativeLinker().downcallHandle($DESC); 59 | 60 | /** 61 | * Invoke the upcall stub {@code funcPtr}, with given parameters 62 | */ 63 | public static void invoke(MemorySegment funcPtr,MemorySegment opaque, long x, long y, long num_pixels, MemorySegment pixels) { 64 | try { 65 | DOWN$MH.invokeExact(funcPtr, opaque, x, y, num_pixels, pixels); 66 | } catch (Throwable ex$) { 67 | throw new AssertionError("should not reach here", ex$); 68 | } 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/JxlMemoryManager.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct JxlMemoryManagerStruct { 18 | * void *opaque; 19 | * jpegxl_alloc_func alloc; 20 | * jpegxl_free_func free; 21 | * } JxlMemoryManager 22 | * } 23 | */ 24 | public class JxlMemoryManager extends JxlMemoryManagerStruct { 25 | 26 | JxlMemoryManager() { 27 | // Should not be called directly 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/JxlParallelRunFunction.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef void (*JxlParallelRunFunction)(void *, uint32_t, size_t) 18 | * } 19 | */ 20 | public class JxlParallelRunFunction { 21 | 22 | JxlParallelRunFunction() { 23 | // Should not be called directly 24 | } 25 | 26 | /** 27 | * The function pointer signature, expressed as a functional interface 28 | */ 29 | public interface Function { 30 | void apply(MemorySegment jpegxl_opaque, int value, long thread_id); 31 | } 32 | 33 | private static final FunctionDescriptor $DESC = FunctionDescriptor.ofVoid( 34 | decode_h.C_POINTER, 35 | decode_h.C_INT, 36 | decode_h.C_LONG 37 | ); 38 | 39 | /** 40 | * The descriptor of this function pointer 41 | */ 42 | public static FunctionDescriptor descriptor() { 43 | return $DESC; 44 | } 45 | 46 | private static final MethodHandle UP$MH = decode_h.upcallHandle(JxlParallelRunFunction.Function.class, "apply", $DESC); 47 | 48 | /** 49 | * Allocates a new upcall stub, whose implementation is defined by {@code fi}. 50 | * The lifetime of the returned segment is managed by {@code arena} 51 | */ 52 | public static MemorySegment allocate(JxlParallelRunFunction.Function fi, Arena arena) { 53 | return Linker.nativeLinker().upcallStub(UP$MH.bindTo(fi), $DESC, arena); 54 | } 55 | 56 | private static final MethodHandle DOWN$MH = Linker.nativeLinker().downcallHandle($DESC); 57 | 58 | /** 59 | * Invoke the upcall stub {@code funcPtr}, with given parameters 60 | */ 61 | public static void invoke(MemorySegment funcPtr,MemorySegment jpegxl_opaque, int value, long thread_id) { 62 | try { 63 | DOWN$MH.invokeExact(funcPtr, jpegxl_opaque, value, thread_id); 64 | } catch (Throwable ex$) { 65 | throw new AssertionError("should not reach here", ex$); 66 | } 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/JxlParallelRunInit.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef JxlParallelRetCode (*JxlParallelRunInit)(void *, size_t) 18 | * } 19 | */ 20 | public class JxlParallelRunInit { 21 | 22 | JxlParallelRunInit() { 23 | // Should not be called directly 24 | } 25 | 26 | /** 27 | * The function pointer signature, expressed as a functional interface 28 | */ 29 | public interface Function { 30 | int apply(MemorySegment jpegxl_opaque, long num_threads); 31 | } 32 | 33 | private static final FunctionDescriptor $DESC = FunctionDescriptor.of( 34 | decode_h.C_INT, 35 | decode_h.C_POINTER, 36 | decode_h.C_LONG 37 | ); 38 | 39 | /** 40 | * The descriptor of this function pointer 41 | */ 42 | public static FunctionDescriptor descriptor() { 43 | return $DESC; 44 | } 45 | 46 | private static final MethodHandle UP$MH = decode_h.upcallHandle(JxlParallelRunInit.Function.class, "apply", $DESC); 47 | 48 | /** 49 | * Allocates a new upcall stub, whose implementation is defined by {@code fi}. 50 | * The lifetime of the returned segment is managed by {@code arena} 51 | */ 52 | public static MemorySegment allocate(JxlParallelRunInit.Function fi, Arena arena) { 53 | return Linker.nativeLinker().upcallStub(UP$MH.bindTo(fi), $DESC, arena); 54 | } 55 | 56 | private static final MethodHandle DOWN$MH = Linker.nativeLinker().downcallHandle($DESC); 57 | 58 | /** 59 | * Invoke the upcall stub {@code funcPtr}, with given parameters 60 | */ 61 | public static int invoke(MemorySegment funcPtr,MemorySegment jpegxl_opaque, long num_threads) { 62 | try { 63 | return (int) DOWN$MH.invokeExact(funcPtr, jpegxl_opaque, num_threads); 64 | } catch (Throwable ex$) { 65 | throw new AssertionError("should not reach here", ex$); 66 | } 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/JxlParallelRunner.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef JxlParallelRetCode (*JxlParallelRunner)(void *, void *, JxlParallelRunInit, JxlParallelRunFunction, uint32_t, uint32_t) 18 | * } 19 | */ 20 | public class JxlParallelRunner { 21 | 22 | JxlParallelRunner() { 23 | // Should not be called directly 24 | } 25 | 26 | /** 27 | * The function pointer signature, expressed as a functional interface 28 | */ 29 | public interface Function { 30 | int apply(MemorySegment runner_opaque, MemorySegment jpegxl_opaque, MemorySegment init, MemorySegment func, int start_range, int end_range); 31 | } 32 | 33 | private static final FunctionDescriptor $DESC = FunctionDescriptor.of( 34 | decode_h.C_INT, 35 | decode_h.C_POINTER, 36 | decode_h.C_POINTER, 37 | decode_h.C_POINTER, 38 | decode_h.C_POINTER, 39 | decode_h.C_INT, 40 | decode_h.C_INT 41 | ); 42 | 43 | /** 44 | * The descriptor of this function pointer 45 | */ 46 | public static FunctionDescriptor descriptor() { 47 | return $DESC; 48 | } 49 | 50 | private static final MethodHandle UP$MH = decode_h.upcallHandle(JxlParallelRunner.Function.class, "apply", $DESC); 51 | 52 | /** 53 | * Allocates a new upcall stub, whose implementation is defined by {@code fi}. 54 | * The lifetime of the returned segment is managed by {@code arena} 55 | */ 56 | public static MemorySegment allocate(JxlParallelRunner.Function fi, Arena arena) { 57 | return Linker.nativeLinker().upcallStub(UP$MH.bindTo(fi), $DESC, arena); 58 | } 59 | 60 | private static final MethodHandle DOWN$MH = Linker.nativeLinker().downcallHandle($DESC); 61 | 62 | /** 63 | * Invoke the upcall stub {@code funcPtr}, with given parameters 64 | */ 65 | public static int invoke(MemorySegment funcPtr,MemorySegment runner_opaque, MemorySegment jpegxl_opaque, MemorySegment init, MemorySegment func, int start_range, int end_range) { 66 | try { 67 | return (int) DOWN$MH.invokeExact(funcPtr, runner_opaque, jpegxl_opaque, init, func, start_range, end_range); 68 | } catch (Throwable ex$) { 69 | throw new AssertionError("should not reach here", ex$); 70 | } 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/JxlPreviewHeader.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * struct { 18 | * uint32_t xsize; 19 | * uint32_t ysize; 20 | * } 21 | * } 22 | */ 23 | public class JxlPreviewHeader { 24 | 25 | JxlPreviewHeader() { 26 | // Should not be called directly 27 | } 28 | 29 | private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( 30 | decode_h.C_INT.withName("xsize"), 31 | decode_h.C_INT.withName("ysize") 32 | ).withName("$anon$65:9"); 33 | 34 | /** 35 | * The layout of this struct 36 | */ 37 | public static final GroupLayout layout() { 38 | return $LAYOUT; 39 | } 40 | 41 | private static final OfInt xsize$LAYOUT = (OfInt)$LAYOUT.select(groupElement("xsize")); 42 | 43 | /** 44 | * Layout for field: 45 | * {@snippet lang=c : 46 | * uint32_t xsize 47 | * } 48 | */ 49 | public static final OfInt xsize$layout() { 50 | return xsize$LAYOUT; 51 | } 52 | 53 | private static final long xsize$OFFSET = 0; 54 | 55 | /** 56 | * Offset for field: 57 | * {@snippet lang=c : 58 | * uint32_t xsize 59 | * } 60 | */ 61 | public static final long xsize$offset() { 62 | return xsize$OFFSET; 63 | } 64 | 65 | /** 66 | * Getter for field: 67 | * {@snippet lang=c : 68 | * uint32_t xsize 69 | * } 70 | */ 71 | public static int xsize(MemorySegment struct) { 72 | return struct.get(xsize$LAYOUT, xsize$OFFSET); 73 | } 74 | 75 | /** 76 | * Setter for field: 77 | * {@snippet lang=c : 78 | * uint32_t xsize 79 | * } 80 | */ 81 | public static void xsize(MemorySegment struct, int fieldValue) { 82 | struct.set(xsize$LAYOUT, xsize$OFFSET, fieldValue); 83 | } 84 | 85 | private static final OfInt ysize$LAYOUT = (OfInt)$LAYOUT.select(groupElement("ysize")); 86 | 87 | /** 88 | * Layout for field: 89 | * {@snippet lang=c : 90 | * uint32_t ysize 91 | * } 92 | */ 93 | public static final OfInt ysize$layout() { 94 | return ysize$LAYOUT; 95 | } 96 | 97 | private static final long ysize$OFFSET = 4; 98 | 99 | /** 100 | * Offset for field: 101 | * {@snippet lang=c : 102 | * uint32_t ysize 103 | * } 104 | */ 105 | public static final long ysize$offset() { 106 | return ysize$OFFSET; 107 | } 108 | 109 | /** 110 | * Getter for field: 111 | * {@snippet lang=c : 112 | * uint32_t ysize 113 | * } 114 | */ 115 | public static int ysize(MemorySegment struct) { 116 | return struct.get(ysize$LAYOUT, ysize$OFFSET); 117 | } 118 | 119 | /** 120 | * Setter for field: 121 | * {@snippet lang=c : 122 | * uint32_t ysize 123 | * } 124 | */ 125 | public static void ysize(MemorySegment struct, int fieldValue) { 126 | struct.set(ysize$LAYOUT, ysize$OFFSET, fieldValue); 127 | } 128 | 129 | /** 130 | * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. 131 | * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} 132 | */ 133 | public static MemorySegment asSlice(MemorySegment array, long index) { 134 | return array.asSlice(layout().byteSize() * index); 135 | } 136 | 137 | /** 138 | * The size (in bytes) of this struct 139 | */ 140 | public static long sizeof() { return layout().byteSize(); } 141 | 142 | /** 143 | * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} 144 | */ 145 | public static MemorySegment allocate(SegmentAllocator allocator) { 146 | return allocator.allocate(layout()); 147 | } 148 | 149 | /** 150 | * Allocate an array of size {@code elementCount} using {@code allocator}. 151 | * The returned segment has size {@code elementCount * layout().byteSize()}. 152 | */ 153 | public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { 154 | return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); 155 | } 156 | 157 | /** 158 | * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). 159 | * The returned segment has size {@code layout().byteSize()} 160 | */ 161 | public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { 162 | return reinterpret(addr, 1, arena, cleanup); 163 | } 164 | 165 | /** 166 | * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). 167 | * The returned segment has size {@code elementCount * layout().byteSize()} 168 | */ 169 | public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { 170 | return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); 171 | } 172 | } 173 | 174 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/__darwin_mbstate_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef __mbstate_t __darwin_mbstate_t 18 | * } 19 | */ 20 | public class __darwin_mbstate_t extends __mbstate_t { 21 | 22 | __darwin_mbstate_t() { 23 | // Should not be called directly 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/__darwin_pthread_attr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_attr_t { 18 | * long __sig; 19 | * char __opaque[56]; 20 | * } __darwin_pthread_attr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_attr_t extends _opaque_pthread_attr_t { 24 | 25 | __darwin_pthread_attr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/__darwin_pthread_cond_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_cond_t { 18 | * long __sig; 19 | * char __opaque[40]; 20 | * } __darwin_pthread_cond_t 21 | * } 22 | */ 23 | public class __darwin_pthread_cond_t extends _opaque_pthread_cond_t { 24 | 25 | __darwin_pthread_cond_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/__darwin_pthread_condattr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_condattr_t { 18 | * long __sig; 19 | * char __opaque[8]; 20 | * } __darwin_pthread_condattr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_condattr_t extends _opaque_pthread_condattr_t { 24 | 25 | __darwin_pthread_condattr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/__darwin_pthread_mutex_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_mutex_t { 18 | * long __sig; 19 | * char __opaque[56]; 20 | * } __darwin_pthread_mutex_t 21 | * } 22 | */ 23 | public class __darwin_pthread_mutex_t extends _opaque_pthread_mutex_t { 24 | 25 | __darwin_pthread_mutex_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/__darwin_pthread_mutexattr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_mutexattr_t { 18 | * long __sig; 19 | * char __opaque[8]; 20 | * } __darwin_pthread_mutexattr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_mutexattr_t extends _opaque_pthread_mutexattr_t { 24 | 25 | __darwin_pthread_mutexattr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/__darwin_pthread_once_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_once_t { 18 | * long __sig; 19 | * char __opaque[8]; 20 | * } __darwin_pthread_once_t 21 | * } 22 | */ 23 | public class __darwin_pthread_once_t extends _opaque_pthread_once_t { 24 | 25 | __darwin_pthread_once_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/__darwin_pthread_rwlock_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_rwlock_t { 18 | * long __sig; 19 | * char __opaque[192]; 20 | * } __darwin_pthread_rwlock_t 21 | * } 22 | */ 23 | public class __darwin_pthread_rwlock_t extends _opaque_pthread_rwlock_t { 24 | 25 | __darwin_pthread_rwlock_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/__darwin_pthread_rwlockattr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_rwlockattr_t { 18 | * long __sig; 19 | * char __opaque[16]; 20 | * } __darwin_pthread_rwlockattr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_rwlockattr_t extends _opaque_pthread_rwlockattr_t { 24 | 25 | __darwin_pthread_rwlockattr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/jpegxl_alloc_func.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef void *(*jpegxl_alloc_func)(void *, size_t) 18 | * } 19 | */ 20 | public class jpegxl_alloc_func { 21 | 22 | jpegxl_alloc_func() { 23 | // Should not be called directly 24 | } 25 | 26 | /** 27 | * The function pointer signature, expressed as a functional interface 28 | */ 29 | public interface Function { 30 | MemorySegment apply(MemorySegment opaque, long size); 31 | } 32 | 33 | private static final FunctionDescriptor $DESC = FunctionDescriptor.of( 34 | decode_h.C_POINTER, 35 | decode_h.C_POINTER, 36 | decode_h.C_LONG 37 | ); 38 | 39 | /** 40 | * The descriptor of this function pointer 41 | */ 42 | public static FunctionDescriptor descriptor() { 43 | return $DESC; 44 | } 45 | 46 | private static final MethodHandle UP$MH = decode_h.upcallHandle(jpegxl_alloc_func.Function.class, "apply", $DESC); 47 | 48 | /** 49 | * Allocates a new upcall stub, whose implementation is defined by {@code fi}. 50 | * The lifetime of the returned segment is managed by {@code arena} 51 | */ 52 | public static MemorySegment allocate(jpegxl_alloc_func.Function fi, Arena arena) { 53 | return Linker.nativeLinker().upcallStub(UP$MH.bindTo(fi), $DESC, arena); 54 | } 55 | 56 | private static final MethodHandle DOWN$MH = Linker.nativeLinker().downcallHandle($DESC); 57 | 58 | /** 59 | * Invoke the upcall stub {@code funcPtr}, with given parameters 60 | */ 61 | public static MemorySegment invoke(MemorySegment funcPtr,MemorySegment opaque, long size) { 62 | try { 63 | return (MemorySegment) DOWN$MH.invokeExact(funcPtr, opaque, size); 64 | } catch (Throwable ex$) { 65 | throw new AssertionError("should not reach here", ex$); 66 | } 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/java22/com/github/gotson/nightmonkeys/jxl/lib/panama/jpegxl_free_func.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.jxl.lib.panama; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef void (*jpegxl_free_func)(void *, void *) 18 | * } 19 | */ 20 | public class jpegxl_free_func { 21 | 22 | jpegxl_free_func() { 23 | // Should not be called directly 24 | } 25 | 26 | /** 27 | * The function pointer signature, expressed as a functional interface 28 | */ 29 | public interface Function { 30 | void apply(MemorySegment opaque, MemorySegment address); 31 | } 32 | 33 | private static final FunctionDescriptor $DESC = FunctionDescriptor.ofVoid( 34 | decode_h.C_POINTER, 35 | decode_h.C_POINTER 36 | ); 37 | 38 | /** 39 | * The descriptor of this function pointer 40 | */ 41 | public static FunctionDescriptor descriptor() { 42 | return $DESC; 43 | } 44 | 45 | private static final MethodHandle UP$MH = decode_h.upcallHandle(jpegxl_free_func.Function.class, "apply", $DESC); 46 | 47 | /** 48 | * Allocates a new upcall stub, whose implementation is defined by {@code fi}. 49 | * The lifetime of the returned segment is managed by {@code arena} 50 | */ 51 | public static MemorySegment allocate(jpegxl_free_func.Function fi, Arena arena) { 52 | return Linker.nativeLinker().upcallStub(UP$MH.bindTo(fi), $DESC, arena); 53 | } 54 | 55 | private static final MethodHandle DOWN$MH = Linker.nativeLinker().downcallHandle($DESC); 56 | 57 | /** 58 | * Invoke the upcall stub {@code funcPtr}, with given parameters 59 | */ 60 | public static void invoke(MemorySegment funcPtr,MemorySegment opaque, MemorySegment address) { 61 | try { 62 | DOWN$MH.invokeExact(funcPtr, opaque, address); 63 | } catch (Throwable ex$) { 64 | throw new AssertionError("should not reach here", ex$); 65 | } 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /imageio-jxl/src/main/resources/META-INF/services/javax.imageio.spi.ImageReaderSpi: -------------------------------------------------------------------------------- 1 | com.github.gotson.nightmonkeys.jxl.imageio.plugins.JxlImageReaderSpi -------------------------------------------------------------------------------- /imageio-jxl/src/test/java/com/github/gotson/nightmonkeys/jxl/imageio/plugins/JpegXlImageReaderTest.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.jxl.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.NoOpImageReaderAbstractTest; 4 | import com.github.gotson.nightmonkeys.common.imageio.ProviderInfo; 5 | 6 | class JpegXlImageReaderTest extends NoOpImageReaderAbstractTest { 7 | @Override 8 | protected ProviderInfo createProvider() { 9 | return new JxlProviderInfo(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /imageio-jxl/src/test/java22/com/github/gotson/nightmonkeys/jxl/imageio/plugins/JpegXlImageReaderTest.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.jxl.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.ImageReaderAbstractTest; 4 | 5 | import javax.imageio.spi.ImageReaderSpi; 6 | import java.awt.Dimension; 7 | import java.util.List; 8 | 9 | import static java.util.Arrays.asList; 10 | 11 | class JpegXlImageReaderTest extends ImageReaderAbstractTest { 12 | 13 | @Override 14 | protected ImageReaderSpi createProvider() { 15 | return new JxlImageReaderSpi(); 16 | } 17 | 18 | @Override 19 | protected List getTestData() { 20 | return asList( 21 | // JPEG XL image, 610x407, lossy, 8-bit RGB+Alpha 22 | new TestData(getClassLoaderResource("/jxl/hills.jxl"), new Dimension(610, 407)), 23 | // JPEG XL image, 1386x924, (possibly) lossless, 10-bit RGB+Alpha 24 | // Orientation: 7 (Anti-Transposed) => we need to invert the width and height 25 | new TestData(getClassLoaderResource("/jxl/island.jxl"), new Dimension(924, 1386)), 26 | // Animation, 12 frames 27 | new TestData(getClassLoaderResource("/jxl/animation.jxl"), new Dimension(256, 256)), 28 | // Grayscale ICC profile 29 | new TestData(getClassLoaderResource("/jxl/gray.jxl"), new Dimension(1561, 2240)) 30 | ); 31 | } 32 | 33 | @Override 34 | protected List getFormatNames() { 35 | return List.of(new JxlProviderInfo().getFormatNames()); 36 | } 37 | 38 | @Override 39 | protected List getSuffixes() { 40 | return List.of(new JxlProviderInfo().getSuffixes()); 41 | } 42 | 43 | @Override 44 | protected List getMIMETypes() { 45 | return List.of(new JxlProviderInfo().getMimeTypes()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /imageio-jxl/src/test/resources/jxl/animation.jxl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-jxl/src/test/resources/jxl/animation.jxl -------------------------------------------------------------------------------- /imageio-jxl/src/test/resources/jxl/gray.jxl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-jxl/src/test/resources/jxl/gray.jxl -------------------------------------------------------------------------------- /imageio-jxl/src/test/resources/jxl/hills.jxl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-jxl/src/test/resources/jxl/hills.jxl -------------------------------------------------------------------------------- /imageio-jxl/src/test/resources/jxl/island.jxl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-jxl/src/test/resources/jxl/island.jxl -------------------------------------------------------------------------------- /imageio-webp/README.md: -------------------------------------------------------------------------------- 1 | # ImageIO WebP plugin 2 | 3 | ## Requirements 4 | 5 | `libwebp` and `libwebpdemux` version 1.2.4+ must be installed on the target system. 6 | 7 | ## Known installations methods 8 | 9 | - Homebrew (Mac & Linux): `brew install webp` 10 | - apt (Linux): `apt-get install libwebp-dev` 11 | 12 | ## Features 13 | 14 | - Decode WebP images (lossless, lossy, and alpha) 15 | - Decode WebP animations. The reader returns the number of images in the animation, and can read individual frames. 16 | - For WebP Containers containing ICC Profile, that profile will be applied on the decoded image. 17 | 18 | ## Limitations 19 | 20 | - Source subsampling doesn't exactly work, it uses the native scaling of `libwebp`, which doesn't have extensive control 21 | for subsampling X and Y. The following will not produce expected results: 22 | 23 | ```java 24 | ImageReadParam param=reader.getDefaultReadParam(); 25 | param.setSourceSubsampling(2,2,0,0); 26 | ``` 27 | 28 | - The Demux API is partially implemented: 29 | - Supported: ICC profile, animation 30 | - Unsupported: EXIF and XMP 31 | 32 | - Source region will snap to even values. This is a limitation from `libwebp`. The following will not produce expected 33 | results: 34 | 35 | ```java 36 | ImageReadParam param=reader.getDefaultReadParam(); 37 | param.setSourceRegion(new Rectangle(3,3,9,9)); 38 | ``` 39 | 40 | ## Implementation notes 41 | 42 | The `panama` package bindings were generated using: 43 | - jextract 22 44 | - from the https://github.com/webmproject/libwebp repository, version 1.2.4 45 | - based on: 46 | - the `decode.h` header file for `panama.webp` 47 | - the `demux.h` header file for `panama.webpdemux` -------------------------------------------------------------------------------- /imageio-webp/build.gradle: -------------------------------------------------------------------------------- 1 | description = 'NightMonkeys :: ImageIO :: WEBP plugin' 2 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java/com/github/gotson/nightmonkeys/webp/imageio/plugins/WebpImageReader.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.webp.imageio.plugins; 2 | 3 | import javax.imageio.ImageReadParam; 4 | import javax.imageio.ImageReader; 5 | import javax.imageio.ImageTypeSpecifier; 6 | import javax.imageio.metadata.IIOMetadata; 7 | import javax.imageio.spi.ImageReaderSpi; 8 | import java.awt.image.BufferedImage; 9 | import java.io.IOException; 10 | import java.util.Iterator; 11 | 12 | public class WebpImageReader extends ImageReader { 13 | 14 | protected WebpImageReader(ImageReaderSpi originatingProvider) { 15 | super(originatingProvider); 16 | } 17 | 18 | /** 19 | * The number of images corresponds to the number of different resolutions that can be directly 20 | * decoded. 21 | */ 22 | @Override 23 | public int getNumImages(boolean allowSearch) { 24 | return 0; 25 | } 26 | 27 | @Override 28 | public int getWidth(int imageIndex) throws IOException { 29 | throw new IOException(); 30 | } 31 | 32 | @Override 33 | public int getHeight(int imageIndex) throws IOException { 34 | throw new IOException(); 35 | } 36 | 37 | @Override 38 | public Iterator getImageTypes(int imageIndex) throws IOException { 39 | throw new IOException(); 40 | } 41 | 42 | @Override 43 | public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException { 44 | throw new IOException(); 45 | } 46 | 47 | @Override 48 | public IIOMetadata getStreamMetadata() { 49 | return null; 50 | } 51 | 52 | @Override 53 | public IIOMetadata getImageMetadata(int imageIndex) { 54 | return null; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java/com/github/gotson/nightmonkeys/webp/imageio/plugins/WebpImageReaderSpi.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.webp.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.ImageReaderSpiBase; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import javax.imageio.ImageReader; 8 | import javax.imageio.spi.ImageReaderSpi; 9 | import javax.imageio.spi.ServiceRegistry; 10 | import javax.imageio.stream.ImageInputStream; 11 | import java.util.Locale; 12 | 13 | public class WebpImageReaderSpi extends ImageReaderSpiBase { 14 | 15 | private static final Logger LOGGER = LoggerFactory.getLogger(WebpImageReaderSpi.class); 16 | 17 | public WebpImageReaderSpi() { 18 | super(new WebpProviderInfo()); 19 | } 20 | 21 | @Override 22 | public void onRegistration(ServiceRegistry registry, Class category) { 23 | LOGGER.info("This plugin only supports Java 22, plugin will be disabled"); 24 | registry.deregisterServiceProvider(this); 25 | super.onRegistration(registry, category); 26 | } 27 | 28 | @Override 29 | public boolean canDecodeInput(Object input) { 30 | return false; 31 | } 32 | 33 | @Override 34 | public ImageReader createReaderInstance(Object extension) { 35 | return new WebpImageReader(this); 36 | } 37 | 38 | @Override 39 | public String getDescription(Locale locale) { 40 | return "WebP reader plugin based on libwebp."; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java/com/github/gotson/nightmonkeys/webp/imageio/plugins/WebpProviderInfo.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.webp.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.ProviderInfo; 4 | 5 | final class WebpProviderInfo extends ProviderInfo { 6 | WebpProviderInfo() { 7 | super( 8 | new String[] {"WebP", "webp"}, 9 | new String[] {"webp"}, 10 | new String[] {"image/webp"}, 11 | "com.github.gotson.nightmonkeys.webp.imageio.plugins.WebpImageReader", 12 | new String[] {"com.github.gotson.nightmonkeys.webp.imageio.plugins.WebpImageReaderSpi"}, 13 | null, 14 | null, 15 | false, 16 | null, 17 | null, 18 | null, 19 | null, 20 | false, 21 | null, 22 | null, 23 | null, 24 | null 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/BasicInfo.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.webp; 2 | 3 | import java.awt.color.ICC_Profile; 4 | 5 | public record BasicInfo( 6 | int width, 7 | int height, 8 | boolean hasAlpha, 9 | boolean hasAnimation, 10 | ICC_Profile iccProfile, 11 | int frameCount 12 | ) { 13 | enum Format { 14 | UNDEFINED_OR_MIXED, 15 | LOSSY, 16 | LOSSLESS 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/WebpException.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.webp; 2 | 3 | public class WebpException extends Exception { 4 | public WebpException(String message) { 5 | super(message); 6 | } 7 | 8 | public WebpException(String message, Throwable cause) { 9 | super(message, cause); 10 | } 11 | 12 | public WebpException(Throwable e) { 13 | super(e); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/imageio/plugins/WebpImageReaderSpi.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.webp.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.ImageReaderSpiBase; 4 | import com.github.gotson.nightmonkeys.webp.WebP; 5 | import com.github.gotson.nightmonkeys.webp.WebpException; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import javax.imageio.ImageIO; 10 | import javax.imageio.ImageReader; 11 | import javax.imageio.spi.ImageReaderSpi; 12 | import javax.imageio.spi.ServiceRegistry; 13 | import javax.imageio.stream.ImageInputStream; 14 | import java.io.IOException; 15 | import java.util.Locale; 16 | 17 | public class WebpImageReaderSpi extends ImageReaderSpiBase { 18 | 19 | private static final Logger LOGGER = LoggerFactory.getLogger(WebpImageReaderSpi.class); 20 | private boolean libLoaded = false; 21 | 22 | public WebpImageReaderSpi() { 23 | super(new WebpProviderInfo()); 24 | } 25 | 26 | private boolean loadLibrary() { 27 | if (!libLoaded) { 28 | try { 29 | LOGGER.info("Loaded libwebp: decoder v{}, demux v{}", WebP.getDecoderVersion(), WebP.getDemuxVersion()); 30 | libLoaded = true; 31 | } catch (UnsatisfiedLinkError e) { 32 | LOGGER.warn("Could not load libwebp, plugin will be disabled. {}", e.getMessage()); 33 | } catch (ExceptionInInitializerError e) { 34 | LOGGER.warn("Native access is disabled, plugin will be disabled. Try adding JVM arguments: --enable-native-access=ALL-UNNAMED"); 35 | } catch (Exception e) { 36 | LOGGER.warn("Unknown error", e); 37 | } 38 | } 39 | return libLoaded; 40 | } 41 | 42 | @Override 43 | public void onRegistration(ServiceRegistry registry, Class category) { 44 | if (!loadLibrary()) { 45 | LOGGER.info("Deregistering service provider"); 46 | registry.deregisterServiceProvider(this); 47 | } 48 | super.onRegistration(registry, category); 49 | } 50 | 51 | @Override 52 | public boolean canDecodeInput(Object input) throws IOException { 53 | if (!(input instanceof ImageInputStream)) { 54 | input = ImageIO.createImageInputStream(input); 55 | } 56 | if (input == null) { 57 | return false; 58 | } 59 | 60 | try { 61 | return WebP.canDecode((ImageInputStream) input); 62 | } catch (WebpException e) { 63 | throw new IOException(e); 64 | } 65 | } 66 | 67 | @Override 68 | public ImageReader createReaderInstance(Object extension) { 69 | return new WebpImageReader(this); 70 | } 71 | 72 | @Override 73 | public String getDescription(Locale locale) { 74 | return "WebP reader plugin based on libwebp."; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/enums/VP8StatusCode.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.webp.lib.enums; 2 | 3 | 4 | import com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux.demux_h; 5 | 6 | public enum VP8StatusCode { 7 | VP8_STATUS_OK(demux_h.VP8_STATUS_OK()), 8 | VP8_STATUS_OUT_OF_MEMORY(demux_h.VP8_STATUS_OUT_OF_MEMORY()), 9 | VP8_STATUS_INVALID_PARAM(demux_h.VP8_STATUS_INVALID_PARAM()), 10 | VP8_STATUS_BITSTREAM_ERROR(demux_h.VP8_STATUS_BITSTREAM_ERROR()), 11 | VP8_STATUS_UNSUPPORTED_FEATURE(demux_h.VP8_STATUS_UNSUPPORTED_FEATURE()), 12 | VP8_STATUS_SUSPENDED(demux_h.VP8_STATUS_SUSPENDED()), 13 | VP8_STATUS_USER_ABORT(demux_h.VP8_STATUS_USER_ABORT()), 14 | VP8_STATUS_NOT_ENOUGH_DATA(demux_h.VP8_STATUS_NOT_ENOUGH_DATA()); 15 | 16 | private final int val; 17 | 18 | VP8StatusCode(int val) { 19 | this.val = val; 20 | } 21 | 22 | public int intValue() { 23 | return val; 24 | } 25 | 26 | public static VP8StatusCode fromId(int id) { 27 | for (VP8StatusCode type : values()) { 28 | if (type.intValue() == id) { 29 | return type; 30 | } 31 | } 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/enums/WebPDemuxState.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.webp.lib.enums; 2 | 3 | 4 | import com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux.demux_h; 5 | 6 | public enum WebPDemuxState { 7 | WEBP_DEMUX_PARSE_ERROR(demux_h.WEBP_DEMUX_PARSE_ERROR()), 8 | WEBP_DEMUX_PARSING_HEADER(demux_h.WEBP_DEMUX_PARSING_HEADER()), 9 | WEBP_DEMUX_PARSED_HEADER(demux_h.WEBP_DEMUX_PARSED_HEADER()), 10 | WEBP_DEMUX_DONE(demux_h.WEBP_DEMUX_DONE()); 11 | 12 | private final int val; 13 | 14 | WebPDemuxState(int val) { 15 | this.val = val; 16 | } 17 | 18 | public int intValue() { 19 | return val; 20 | } 21 | 22 | public static WebPDemuxState fromId(int id) { 23 | for (WebPDemuxState type : values()) { 24 | if (type.intValue() == id) { 25 | return type; 26 | } 27 | } 28 | return null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/enums/WebPFeatureFlags.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.webp.lib.enums; 2 | 3 | 4 | import com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux.demux_h; 5 | 6 | import java.util.Arrays; 7 | import java.util.EnumSet; 8 | import java.util.stream.Collectors; 9 | 10 | public enum WebPFeatureFlags { 11 | ANIMATION_FLAG(demux_h.ANIMATION_FLAG()), 12 | XMP_FLAG(demux_h.XMP_FLAG()), 13 | EXIF_FLAG(demux_h.EXIF_FLAG()), 14 | ALPHA_FLAG(demux_h.ALPHA_FLAG()), 15 | ICCP_FLAG(demux_h.ICCP_FLAG()), 16 | ALL_VALID_FLAGS(demux_h.ALL_VALID_FLAGS()); 17 | 18 | private final int val; 19 | 20 | WebPFeatureFlags(int val) { 21 | this.val = val; 22 | } 23 | 24 | public int intValue() { 25 | return val; 26 | } 27 | 28 | public static EnumSet parseInt(int flags) { 29 | return Arrays.stream(values()) 30 | .filter(type -> (flags & type.intValue()) == type.intValue()) 31 | .collect(Collectors.toCollection(() -> EnumSet.noneOf(WebPFeatureFlags.class))); 32 | } 33 | 34 | public static WebPFeatureFlags fromId(int id) { 35 | for (WebPFeatureFlags type : values()) { 36 | if (type.intValue() == id) { 37 | return type; 38 | } 39 | } 40 | return null; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/enums/WebPFormatFeature.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.webp.lib.enums; 2 | 3 | 4 | import com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux.demux_h; 5 | 6 | public enum WebPFormatFeature { 7 | /** 8 | * bit-wise combination of WebPFeatureFlags 9 | * corresponding to the 'VP8X' chunk (if present). 10 | */ 11 | WEBP_FF_FORMAT_FLAGS(demux_h.WEBP_FF_FORMAT_FLAGS()), 12 | WEBP_FF_CANVAS_WIDTH(demux_h.WEBP_FF_CANVAS_WIDTH()), 13 | WEBP_FF_CANVAS_HEIGHT(demux_h.WEBP_FF_CANVAS_HEIGHT()), 14 | 15 | /** 16 | * only relevant for animated file 17 | */ 18 | WEBP_FF_LOOP_COUNT(demux_h.WEBP_FF_LOOP_COUNT()), 19 | 20 | /** 21 | * only relevant for animated file 22 | */ 23 | WEBP_FF_BACKGROUND_COLOR(demux_h.WEBP_FF_BACKGROUND_COLOR()), 24 | 25 | /** 26 | * Number of frames present in the demux object. 27 | * In case of a partial demux, this is the number 28 | * of frames seen so far, with the last frame 29 | * possibly being partial. 30 | */ 31 | WEBP_FF_FRAME_COUNT(demux_h.WEBP_FF_FRAME_COUNT()); 32 | 33 | private final int val; 34 | 35 | WebPFormatFeature(int val) { 36 | this.val = val; 37 | } 38 | 39 | public int intValue() { 40 | return val; 41 | } 42 | 43 | public static WebPFormatFeature fromId(int id) { 44 | for (WebPFormatFeature type : values()) { 45 | if (type.intValue() == id) { 46 | return type; 47 | } 48 | } 49 | return null; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webp/__darwin_mbstate_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webp; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef __mbstate_t __darwin_mbstate_t 18 | * } 19 | */ 20 | public class __darwin_mbstate_t extends __mbstate_t { 21 | 22 | __darwin_mbstate_t() { 23 | // Should not be called directly 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webp/__darwin_pthread_attr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webp; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_attr_t { 18 | * long __sig; 19 | * char __opaque[56]; 20 | * } __darwin_pthread_attr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_attr_t extends _opaque_pthread_attr_t { 24 | 25 | __darwin_pthread_attr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webp/__darwin_pthread_cond_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webp; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_cond_t { 18 | * long __sig; 19 | * char __opaque[40]; 20 | * } __darwin_pthread_cond_t 21 | * } 22 | */ 23 | public class __darwin_pthread_cond_t extends _opaque_pthread_cond_t { 24 | 25 | __darwin_pthread_cond_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webp/__darwin_pthread_condattr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webp; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_condattr_t { 18 | * long __sig; 19 | * char __opaque[8]; 20 | * } __darwin_pthread_condattr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_condattr_t extends _opaque_pthread_condattr_t { 24 | 25 | __darwin_pthread_condattr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webp/__darwin_pthread_mutex_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webp; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_mutex_t { 18 | * long __sig; 19 | * char __opaque[56]; 20 | * } __darwin_pthread_mutex_t 21 | * } 22 | */ 23 | public class __darwin_pthread_mutex_t extends _opaque_pthread_mutex_t { 24 | 25 | __darwin_pthread_mutex_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webp/__darwin_pthread_mutexattr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webp; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_mutexattr_t { 18 | * long __sig; 19 | * char __opaque[8]; 20 | * } __darwin_pthread_mutexattr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_mutexattr_t extends _opaque_pthread_mutexattr_t { 24 | 25 | __darwin_pthread_mutexattr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webp/__darwin_pthread_once_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webp; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_once_t { 18 | * long __sig; 19 | * char __opaque[8]; 20 | * } __darwin_pthread_once_t 21 | * } 22 | */ 23 | public class __darwin_pthread_once_t extends _opaque_pthread_once_t { 24 | 25 | __darwin_pthread_once_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webp/__darwin_pthread_rwlock_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webp; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_rwlock_t { 18 | * long __sig; 19 | * char __opaque[192]; 20 | * } __darwin_pthread_rwlock_t 21 | * } 22 | */ 23 | public class __darwin_pthread_rwlock_t extends _opaque_pthread_rwlock_t { 24 | 25 | __darwin_pthread_rwlock_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webp/__darwin_pthread_rwlockattr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webp; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_rwlockattr_t { 18 | * long __sig; 19 | * char __opaque[16]; 20 | * } __darwin_pthread_rwlockattr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_rwlockattr_t extends _opaque_pthread_rwlockattr_t { 24 | 25 | __darwin_pthread_rwlockattr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webp/imaxdiv_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webp; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * struct { 18 | * intmax_t quot; 19 | * intmax_t rem; 20 | * } 21 | * } 22 | */ 23 | public class imaxdiv_t { 24 | 25 | imaxdiv_t() { 26 | // Should not be called directly 27 | } 28 | 29 | private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( 30 | decode_h.C_LONG.withName("quot"), 31 | decode_h.C_LONG.withName("rem") 32 | ).withName("$anon$239:9"); 33 | 34 | /** 35 | * The layout of this struct 36 | */ 37 | public static final GroupLayout layout() { 38 | return $LAYOUT; 39 | } 40 | 41 | private static final OfLong quot$LAYOUT = (OfLong)$LAYOUT.select(groupElement("quot")); 42 | 43 | /** 44 | * Layout for field: 45 | * {@snippet lang=c : 46 | * intmax_t quot 47 | * } 48 | */ 49 | public static final OfLong quot$layout() { 50 | return quot$LAYOUT; 51 | } 52 | 53 | private static final long quot$OFFSET = 0; 54 | 55 | /** 56 | * Offset for field: 57 | * {@snippet lang=c : 58 | * intmax_t quot 59 | * } 60 | */ 61 | public static final long quot$offset() { 62 | return quot$OFFSET; 63 | } 64 | 65 | /** 66 | * Getter for field: 67 | * {@snippet lang=c : 68 | * intmax_t quot 69 | * } 70 | */ 71 | public static long quot(MemorySegment struct) { 72 | return struct.get(quot$LAYOUT, quot$OFFSET); 73 | } 74 | 75 | /** 76 | * Setter for field: 77 | * {@snippet lang=c : 78 | * intmax_t quot 79 | * } 80 | */ 81 | public static void quot(MemorySegment struct, long fieldValue) { 82 | struct.set(quot$LAYOUT, quot$OFFSET, fieldValue); 83 | } 84 | 85 | private static final OfLong rem$LAYOUT = (OfLong)$LAYOUT.select(groupElement("rem")); 86 | 87 | /** 88 | * Layout for field: 89 | * {@snippet lang=c : 90 | * intmax_t rem 91 | * } 92 | */ 93 | public static final OfLong rem$layout() { 94 | return rem$LAYOUT; 95 | } 96 | 97 | private static final long rem$OFFSET = 8; 98 | 99 | /** 100 | * Offset for field: 101 | * {@snippet lang=c : 102 | * intmax_t rem 103 | * } 104 | */ 105 | public static final long rem$offset() { 106 | return rem$OFFSET; 107 | } 108 | 109 | /** 110 | * Getter for field: 111 | * {@snippet lang=c : 112 | * intmax_t rem 113 | * } 114 | */ 115 | public static long rem(MemorySegment struct) { 116 | return struct.get(rem$LAYOUT, rem$OFFSET); 117 | } 118 | 119 | /** 120 | * Setter for field: 121 | * {@snippet lang=c : 122 | * intmax_t rem 123 | * } 124 | */ 125 | public static void rem(MemorySegment struct, long fieldValue) { 126 | struct.set(rem$LAYOUT, rem$OFFSET, fieldValue); 127 | } 128 | 129 | /** 130 | * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. 131 | * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} 132 | */ 133 | public static MemorySegment asSlice(MemorySegment array, long index) { 134 | return array.asSlice(layout().byteSize() * index); 135 | } 136 | 137 | /** 138 | * The size (in bytes) of this struct 139 | */ 140 | public static long sizeof() { return layout().byteSize(); } 141 | 142 | /** 143 | * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} 144 | */ 145 | public static MemorySegment allocate(SegmentAllocator allocator) { 146 | return allocator.allocate(layout()); 147 | } 148 | 149 | /** 150 | * Allocate an array of size {@code elementCount} using {@code allocator}. 151 | * The returned segment has size {@code elementCount * layout().byteSize()}. 152 | */ 153 | public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { 154 | return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); 155 | } 156 | 157 | /** 158 | * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). 159 | * The returned segment has size {@code layout().byteSize()} 160 | */ 161 | public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { 162 | return reinterpret(addr, 1, arena, cleanup); 163 | } 164 | 165 | /** 166 | * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). 167 | * The returned segment has size {@code elementCount * layout().byteSize()} 168 | */ 169 | public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { 170 | return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); 171 | } 172 | } 173 | 174 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webpdemux/WebPData.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * struct WebPData { 18 | * const uint8_t *bytes; 19 | * size_t size; 20 | * } 21 | * } 22 | */ 23 | public class WebPData { 24 | 25 | WebPData() { 26 | // Should not be called directly 27 | } 28 | 29 | private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( 30 | demux_h.C_POINTER.withName("bytes"), 31 | demux_h.C_LONG.withName("size") 32 | ).withName("WebPData"); 33 | 34 | /** 35 | * The layout of this struct 36 | */ 37 | public static final GroupLayout layout() { 38 | return $LAYOUT; 39 | } 40 | 41 | private static final AddressLayout bytes$LAYOUT = (AddressLayout)$LAYOUT.select(groupElement("bytes")); 42 | 43 | /** 44 | * Layout for field: 45 | * {@snippet lang=c : 46 | * const uint8_t *bytes 47 | * } 48 | */ 49 | public static final AddressLayout bytes$layout() { 50 | return bytes$LAYOUT; 51 | } 52 | 53 | private static final long bytes$OFFSET = 0; 54 | 55 | /** 56 | * Offset for field: 57 | * {@snippet lang=c : 58 | * const uint8_t *bytes 59 | * } 60 | */ 61 | public static final long bytes$offset() { 62 | return bytes$OFFSET; 63 | } 64 | 65 | /** 66 | * Getter for field: 67 | * {@snippet lang=c : 68 | * const uint8_t *bytes 69 | * } 70 | */ 71 | public static MemorySegment bytes(MemorySegment struct) { 72 | return struct.get(bytes$LAYOUT, bytes$OFFSET); 73 | } 74 | 75 | /** 76 | * Setter for field: 77 | * {@snippet lang=c : 78 | * const uint8_t *bytes 79 | * } 80 | */ 81 | public static void bytes(MemorySegment struct, MemorySegment fieldValue) { 82 | struct.set(bytes$LAYOUT, bytes$OFFSET, fieldValue); 83 | } 84 | 85 | private static final OfLong size$LAYOUT = (OfLong)$LAYOUT.select(groupElement("size")); 86 | 87 | /** 88 | * Layout for field: 89 | * {@snippet lang=c : 90 | * size_t size 91 | * } 92 | */ 93 | public static final OfLong size$layout() { 94 | return size$LAYOUT; 95 | } 96 | 97 | private static final long size$OFFSET = 8; 98 | 99 | /** 100 | * Offset for field: 101 | * {@snippet lang=c : 102 | * size_t size 103 | * } 104 | */ 105 | public static final long size$offset() { 106 | return size$OFFSET; 107 | } 108 | 109 | /** 110 | * Getter for field: 111 | * {@snippet lang=c : 112 | * size_t size 113 | * } 114 | */ 115 | public static long size(MemorySegment struct) { 116 | return struct.get(size$LAYOUT, size$OFFSET); 117 | } 118 | 119 | /** 120 | * Setter for field: 121 | * {@snippet lang=c : 122 | * size_t size 123 | * } 124 | */ 125 | public static void size(MemorySegment struct, long fieldValue) { 126 | struct.set(size$LAYOUT, size$OFFSET, fieldValue); 127 | } 128 | 129 | /** 130 | * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. 131 | * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} 132 | */ 133 | public static MemorySegment asSlice(MemorySegment array, long index) { 134 | return array.asSlice(layout().byteSize() * index); 135 | } 136 | 137 | /** 138 | * The size (in bytes) of this struct 139 | */ 140 | public static long sizeof() { return layout().byteSize(); } 141 | 142 | /** 143 | * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} 144 | */ 145 | public static MemorySegment allocate(SegmentAllocator allocator) { 146 | return allocator.allocate(layout()); 147 | } 148 | 149 | /** 150 | * Allocate an array of size {@code elementCount} using {@code allocator}. 151 | * The returned segment has size {@code elementCount * layout().byteSize()}. 152 | */ 153 | public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { 154 | return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); 155 | } 156 | 157 | /** 158 | * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). 159 | * The returned segment has size {@code layout().byteSize()} 160 | */ 161 | public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { 162 | return reinterpret(addr, 1, arena, cleanup); 163 | } 164 | 165 | /** 166 | * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). 167 | * The returned segment has size {@code elementCount * layout().byteSize()} 168 | */ 169 | public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { 170 | return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); 171 | } 172 | } 173 | 174 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webpdemux/__darwin_mbstate_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef __mbstate_t __darwin_mbstate_t 18 | * } 19 | */ 20 | public class __darwin_mbstate_t extends __mbstate_t { 21 | 22 | __darwin_mbstate_t() { 23 | // Should not be called directly 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webpdemux/__darwin_pthread_attr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_attr_t { 18 | * long __sig; 19 | * char __opaque[56]; 20 | * } __darwin_pthread_attr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_attr_t extends _opaque_pthread_attr_t { 24 | 25 | __darwin_pthread_attr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webpdemux/__darwin_pthread_cond_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_cond_t { 18 | * long __sig; 19 | * char __opaque[40]; 20 | * } __darwin_pthread_cond_t 21 | * } 22 | */ 23 | public class __darwin_pthread_cond_t extends _opaque_pthread_cond_t { 24 | 25 | __darwin_pthread_cond_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webpdemux/__darwin_pthread_condattr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_condattr_t { 18 | * long __sig; 19 | * char __opaque[8]; 20 | * } __darwin_pthread_condattr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_condattr_t extends _opaque_pthread_condattr_t { 24 | 25 | __darwin_pthread_condattr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webpdemux/__darwin_pthread_mutex_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_mutex_t { 18 | * long __sig; 19 | * char __opaque[56]; 20 | * } __darwin_pthread_mutex_t 21 | * } 22 | */ 23 | public class __darwin_pthread_mutex_t extends _opaque_pthread_mutex_t { 24 | 25 | __darwin_pthread_mutex_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webpdemux/__darwin_pthread_mutexattr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_mutexattr_t { 18 | * long __sig; 19 | * char __opaque[8]; 20 | * } __darwin_pthread_mutexattr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_mutexattr_t extends _opaque_pthread_mutexattr_t { 24 | 25 | __darwin_pthread_mutexattr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webpdemux/__darwin_pthread_once_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_once_t { 18 | * long __sig; 19 | * char __opaque[8]; 20 | * } __darwin_pthread_once_t 21 | * } 22 | */ 23 | public class __darwin_pthread_once_t extends _opaque_pthread_once_t { 24 | 25 | __darwin_pthread_once_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webpdemux/__darwin_pthread_rwlock_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_rwlock_t { 18 | * long __sig; 19 | * char __opaque[192]; 20 | * } __darwin_pthread_rwlock_t 21 | * } 22 | */ 23 | public class __darwin_pthread_rwlock_t extends _opaque_pthread_rwlock_t { 24 | 25 | __darwin_pthread_rwlock_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webpdemux/__darwin_pthread_rwlockattr_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * typedef struct _opaque_pthread_rwlockattr_t { 18 | * long __sig; 19 | * char __opaque[16]; 20 | * } __darwin_pthread_rwlockattr_t 21 | * } 22 | */ 23 | public class __darwin_pthread_rwlockattr_t extends _opaque_pthread_rwlockattr_t { 24 | 25 | __darwin_pthread_rwlockattr_t() { 26 | // Should not be called directly 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /imageio-webp/src/main/java22/com/github/gotson/nightmonkeys/webp/lib/panama/webpdemux/imaxdiv_t.java: -------------------------------------------------------------------------------- 1 | // Generated by jextract 2 | 3 | package com.github.gotson.nightmonkeys.webp.lib.panama.webpdemux; 4 | 5 | import java.lang.invoke.*; 6 | import java.lang.foreign.*; 7 | import java.nio.ByteOrder; 8 | import java.util.*; 9 | import java.util.function.*; 10 | import java.util.stream.*; 11 | 12 | import static java.lang.foreign.ValueLayout.*; 13 | import static java.lang.foreign.MemoryLayout.PathElement.*; 14 | 15 | /** 16 | * {@snippet lang=c : 17 | * struct { 18 | * intmax_t quot; 19 | * intmax_t rem; 20 | * } 21 | * } 22 | */ 23 | public class imaxdiv_t { 24 | 25 | imaxdiv_t() { 26 | // Should not be called directly 27 | } 28 | 29 | private static final GroupLayout $LAYOUT = MemoryLayout.structLayout( 30 | demux_h.C_LONG.withName("quot"), 31 | demux_h.C_LONG.withName("rem") 32 | ).withName("$anon$239:9"); 33 | 34 | /** 35 | * The layout of this struct 36 | */ 37 | public static final GroupLayout layout() { 38 | return $LAYOUT; 39 | } 40 | 41 | private static final OfLong quot$LAYOUT = (OfLong)$LAYOUT.select(groupElement("quot")); 42 | 43 | /** 44 | * Layout for field: 45 | * {@snippet lang=c : 46 | * intmax_t quot 47 | * } 48 | */ 49 | public static final OfLong quot$layout() { 50 | return quot$LAYOUT; 51 | } 52 | 53 | private static final long quot$OFFSET = 0; 54 | 55 | /** 56 | * Offset for field: 57 | * {@snippet lang=c : 58 | * intmax_t quot 59 | * } 60 | */ 61 | public static final long quot$offset() { 62 | return quot$OFFSET; 63 | } 64 | 65 | /** 66 | * Getter for field: 67 | * {@snippet lang=c : 68 | * intmax_t quot 69 | * } 70 | */ 71 | public static long quot(MemorySegment struct) { 72 | return struct.get(quot$LAYOUT, quot$OFFSET); 73 | } 74 | 75 | /** 76 | * Setter for field: 77 | * {@snippet lang=c : 78 | * intmax_t quot 79 | * } 80 | */ 81 | public static void quot(MemorySegment struct, long fieldValue) { 82 | struct.set(quot$LAYOUT, quot$OFFSET, fieldValue); 83 | } 84 | 85 | private static final OfLong rem$LAYOUT = (OfLong)$LAYOUT.select(groupElement("rem")); 86 | 87 | /** 88 | * Layout for field: 89 | * {@snippet lang=c : 90 | * intmax_t rem 91 | * } 92 | */ 93 | public static final OfLong rem$layout() { 94 | return rem$LAYOUT; 95 | } 96 | 97 | private static final long rem$OFFSET = 8; 98 | 99 | /** 100 | * Offset for field: 101 | * {@snippet lang=c : 102 | * intmax_t rem 103 | * } 104 | */ 105 | public static final long rem$offset() { 106 | return rem$OFFSET; 107 | } 108 | 109 | /** 110 | * Getter for field: 111 | * {@snippet lang=c : 112 | * intmax_t rem 113 | * } 114 | */ 115 | public static long rem(MemorySegment struct) { 116 | return struct.get(rem$LAYOUT, rem$OFFSET); 117 | } 118 | 119 | /** 120 | * Setter for field: 121 | * {@snippet lang=c : 122 | * intmax_t rem 123 | * } 124 | */ 125 | public static void rem(MemorySegment struct, long fieldValue) { 126 | struct.set(rem$LAYOUT, rem$OFFSET, fieldValue); 127 | } 128 | 129 | /** 130 | * Obtains a slice of {@code arrayParam} which selects the array element at {@code index}. 131 | * The returned segment has address {@code arrayParam.address() + index * layout().byteSize()} 132 | */ 133 | public static MemorySegment asSlice(MemorySegment array, long index) { 134 | return array.asSlice(layout().byteSize() * index); 135 | } 136 | 137 | /** 138 | * The size (in bytes) of this struct 139 | */ 140 | public static long sizeof() { return layout().byteSize(); } 141 | 142 | /** 143 | * Allocate a segment of size {@code layout().byteSize()} using {@code allocator} 144 | */ 145 | public static MemorySegment allocate(SegmentAllocator allocator) { 146 | return allocator.allocate(layout()); 147 | } 148 | 149 | /** 150 | * Allocate an array of size {@code elementCount} using {@code allocator}. 151 | * The returned segment has size {@code elementCount * layout().byteSize()}. 152 | */ 153 | public static MemorySegment allocateArray(long elementCount, SegmentAllocator allocator) { 154 | return allocator.allocate(MemoryLayout.sequenceLayout(elementCount, layout())); 155 | } 156 | 157 | /** 158 | * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). 159 | * The returned segment has size {@code layout().byteSize()} 160 | */ 161 | public static MemorySegment reinterpret(MemorySegment addr, Arena arena, Consumer cleanup) { 162 | return reinterpret(addr, 1, arena, cleanup); 163 | } 164 | 165 | /** 166 | * Reinterprets {@code addr} using target {@code arena} and {@code cleanupAction} (if any). 167 | * The returned segment has size {@code elementCount * layout().byteSize()} 168 | */ 169 | public static MemorySegment reinterpret(MemorySegment addr, long elementCount, Arena arena, Consumer cleanup) { 170 | return addr.reinterpret(layout().byteSize() * elementCount, arena, cleanup); 171 | } 172 | } 173 | 174 | -------------------------------------------------------------------------------- /imageio-webp/src/main/resources/META-INF/services/javax.imageio.spi.ImageReaderSpi: -------------------------------------------------------------------------------- 1 | com.github.gotson.nightmonkeys.webp.imageio.plugins.WebpImageReaderSpi -------------------------------------------------------------------------------- /imageio-webp/src/test/java/com/github/gotson/nightmonkeys/webp/imageio/plugins/WebpImageReaderTest.java: -------------------------------------------------------------------------------- 1 | package com.github.gotson.nightmonkeys.webp.imageio.plugins; 2 | 3 | import com.github.gotson.nightmonkeys.common.imageio.NoOpImageReaderAbstractTest; 4 | import com.github.gotson.nightmonkeys.common.imageio.ProviderInfo; 5 | 6 | class WebpImageReaderTest extends NoOpImageReaderAbstractTest { 7 | @Override 8 | protected ProviderInfo createProvider() { 9 | return new WebpProviderInfo(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/1.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/1_webp_a.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/1_webp_a.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/1_webp_ll.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/1_webp_ll.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/2_webp_a.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/2_webp_a.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/2_webp_ll.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/2_webp_ll.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/2_webp_ll_alt.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/2_webp_ll_alt.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/3_webp_a.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/3_webp_a.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/3_webp_ll.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/3_webp_ll.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/4_webp_a.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/4_webp_a.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/4_webp_ll.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/4_webp_ll.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/5.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/5.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/5_webp_a.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/5_webp_a.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/5_webp_ll.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/5_webp_ll.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/alpha_filter.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/alpha_filter.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/animated-banana.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/animated-banana.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/animated-webp-supported.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/animated-webp-supported.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/blue_tile.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/blue_tile.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/bug3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/bug3.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/gray.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/gray.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/photo-iccp-adobergb.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/photo-iccp-adobergb.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/segment01.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/segment01.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/segment02.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/segment02.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/segment03.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/segment03.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/small_13x1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/small_13x1.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/small_1x1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/small_1x1.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/small_1x13.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/small_1x13.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/small_31x13.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/small_31x13.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/test.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/test.webp -------------------------------------------------------------------------------- /imageio-webp/src/test/resources/webp/very_short.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/imageio-webp/src/test/resources/webp/very_short.webp -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'NightMonkeys' 2 | include(':imageio-common') 3 | include(':imageio-jxl') 4 | include(':imageio-webp') 5 | include(':imageio-heif') 6 | -------------------------------------------------------------------------------- /test-libraries/windows/x64/aom.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/aom.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/brotlicommon.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/brotlicommon.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/brotlidec.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/brotlidec.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/brotlienc.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/brotlienc.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/dav1d.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/dav1d.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/heif.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/heif.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/hwy.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/hwy.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/jxl.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/jxl.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/jxl_threads.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/jxl_threads.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/lcms2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/lcms2.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/libde265.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/libde265.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/libsharpyuv.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/libsharpyuv.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/libwebp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/libwebp.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/libwebpdecoder.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/libwebpdecoder.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/libwebpmux.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/libwebpmux.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/libx265.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/libx265.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/webp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/webp.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/webpdemux.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/webpdemux.dll -------------------------------------------------------------------------------- /test-libraries/windows/x64/zlib1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gotson/NightMonkeys/4b5fe95f07fd09ad3bc23404b044850bc9d4a052/test-libraries/windows/x64/zlib1.dll --------------------------------------------------------------------------------