Compare commits

..

16 Commits

Author SHA1 Message Date
Harald Kuhr 2ad522a9fa [maven-release-plugin] prepare release twelvemonkeys-3.13.1 2026-02-22 16:13:44 +01:00
dependabot[bot] 20af575fbd Bump github/codeql-action from 4.31.10 to 4.32.2 in /.github/workflows
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.31.10 to 4.32.2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/cdefb33c0f6224e58673d9004f47f7cb3e328b89...45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.32.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 11:08:19 +01:00
dependabot[bot] 02a6ed1ac1 Bump mikepenz/action-junit-report in /.github/workflows
Bumps [mikepenz/action-junit-report](https://github.com/mikepenz/action-junit-report) from 6.1.0 to 6.2.0.
- [Release notes](https://github.com/mikepenz/action-junit-report/releases)
- [Commits](https://github.com/mikepenz/action-junit-report/compare/a294a61c909bd8a4b563024a2faa28897fd53ebc...74626db7353a25a20a72816467ebf035f674c5f8)

---
updated-dependencies:
- dependency-name: mikepenz/action-junit-report
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-09 10:28:21 +01:00
Harald Kuhr 146d5926bb #1244: Created test + fixed inverted PSD hidden flag in metadata 2026-02-05 13:54:51 +01:00
dependabot[bot] 561b25022c Bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.14.1 to 3.15.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.14.1...maven-compiler-plugin-3.15.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-version: 3.15.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-03 11:09:22 +01:00
dependabot[bot] 4cd6b893de Bump actions/setup-java from 5.1.0 to 5.2.0 in /.github/workflows
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5.1.0 to 5.2.0.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/f2beeb24e141e01a676f977032f5a29d81c9e27e...be666c2fcd27ec809703dec50e508c2fdc7f6654)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: 5.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-29 13:45:17 +01:00
dependabot[bot] dabff3abce Bump actions/checkout from 6.0.1 to 6.0.2 in /.github/workflows
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/8e8c483db84b4bee98b60c0593521ed34d9990e8...de0fac2e4500dabe0009e67214ff5f5447ce83dd)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-23 09:50:45 +01:00
Will Ezell 1b889b1b4b Fixes Lossless Alpha Channel WebP (#1243)
* Fix alpha channel dimensions in WebP lossless decoding

  Use the expected width and height values instead of tempRaster.getWidth()/getHeight() when creating the alpha channel's writable child raster. This ensures the alpha channel is correctly sized when the temp raster dimensions differ from the expected dimensions.

* Fixes Lossless Huffman table based on libwebp

* Remove redundant flush call in image reader test

Removed unnecessary image.flush() call in WebPImageReaderTest.

* adding code to generate good hash for reproducability
2026-01-23 09:40:06 +01:00
dependabot[bot] 29a3bd591d Bump github/codeql-action from 4.31.9 to 4.31.10 in /.github/workflows
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.31.9 to 4.31.10.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/5d4e8d1aca955e8d8589aabd499c5cae939e33c7...cdefb33c0f6224e58673d9004f47f7cb3e328b89)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.31.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-20 13:25:57 +01:00
Harald Kuhr cd79ef4409 #1240: Fixes TIFFWriter overwrite of nested values issue 2026-01-15 19:42:56 +01:00
dependabot[bot] a604cb83fb Bump org.sonatype.central:central-publishing-maven-plugin
Bumps [org.sonatype.central:central-publishing-maven-plugin](https://github.com/sonatype/central-publishing-maven-plugin) from 0.9.0 to 0.10.0.
- [Commits](https://github.com/sonatype/central-publishing-maven-plugin/commits)

---
updated-dependencies:
- dependency-name: org.sonatype.central:central-publishing-maven-plugin
  dependency-version: 0.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-15 10:50:33 +01:00
dependabot[bot] eb1735ab33 Bump junit.jupiter.version from 5.14.1 to 5.14.2
Bumps `junit.jupiter.version` from 5.14.1 to 5.14.2.

Updates `org.junit.jupiter:junit-jupiter-api` from 5.14.1 to 5.14.2
- [Release notes](https://github.com/junit-team/junit-framework/releases)
- [Commits](https://github.com/junit-team/junit-framework/compare/r5.14.1...r5.14.2)

Updates `org.junit.jupiter:junit-jupiter-engine` from 5.14.1 to 5.14.2
- [Release notes](https://github.com/junit-team/junit-framework/releases)
- [Commits](https://github.com/junit-team/junit-framework/compare/r5.14.1...r5.14.2)

---
updated-dependencies:
- dependency-name: org.junit.jupiter:junit-jupiter-api
  dependency-version: 5.14.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.junit.jupiter:junit-jupiter-engine
  dependency-version: 5.14.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-14 11:25:14 +01:00
dependabot[bot] 357eeb2236 Bump mikepenz/action-junit-report in /.github/workflows
Bumps [mikepenz/action-junit-report](https://github.com/mikepenz/action-junit-report) from 6.0.1 to 6.1.0.
- [Release notes](https://github.com/mikepenz/action-junit-report/releases)
- [Commits](https://github.com/mikepenz/action-junit-report/compare/e08919a3b1fb83a78393dfb775a9c37f17d8eea6...a294a61c909bd8a4b563024a2faa28897fd53ebc)

---
updated-dependencies:
- dependency-name: mikepenz/action-junit-report
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-07 10:59:50 +01:00
dependabot[bot] d634b9d93f Bump github/codeql-action from 4.31.4 to 4.31.9 in /.github/workflows
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.31.4 to 4.31.9.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e12f0178983d466f2f6028f5cc7a6d786fd97f4b...5d4e8d1aca955e8d8589aabd499c5cae939e33c7)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.31.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-05 22:18:20 +01:00
dependabot[bot] 7e3241d64b Bump org.sonatype.central:central-publishing-maven-plugin
Bumps [org.sonatype.central:central-publishing-maven-plugin](https://github.com/sonatype/central-publishing-maven-plugin) from 0.7.0 to 0.9.0.
- [Commits](https://github.com/sonatype/central-publishing-maven-plugin/commits)

---
updated-dependencies:
- dependency-name: org.sonatype.central:central-publishing-maven-plugin
  dependency-version: 0.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-23 10:53:27 +01:00
Harald Kuhr b86d82720d [maven-release-plugin] prepare for next development iteration 2025-12-22 15:40:16 +01:00
47 changed files with 388 additions and 117 deletions
+11 -11
View File
@@ -22,8 +22,8 @@ jobs:
permissions:
checks: write
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: 'temurin'
java-version: ${{ matrix.java }}
@@ -32,7 +32,7 @@ jobs:
- name: Run Tests
run: mvn --batch-mode --no-transfer-progress test
- name: Publish Test Report
uses: mikepenz/action-junit-report@e08919a3b1fb83a78393dfb775a9c37f17d8eea6 # v5
uses: mikepenz/action-junit-report@74626db7353a25a20a72816467ebf035f674c5f8 # v5
if: ${{ !cancelled() }}
with:
report_paths: "**/target/surefire-reports/TEST*.xml"
@@ -48,8 +48,8 @@ jobs:
permissions:
checks: write
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: 'zulu'
java-version: '8'
@@ -58,7 +58,7 @@ jobs:
- name: Run Tests
run: mvn --batch-mode --no-transfer-progress test
- name: Publish Test Report
uses: mikepenz/action-junit-report@e08919a3b1fb83a78393dfb775a9c37f17d8eea6 # v5
uses: mikepenz/action-junit-report@74626db7353a25a20a72816467ebf035f674c5f8 # v5
if: ${{ !cancelled() }}
with:
report_paths: "**/target/surefire-reports/TEST*.xml"
@@ -73,11 +73,11 @@ jobs:
matrix:
kcms: [ true, false ]
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- run: |
download_url="https://javadl.oracle.com/webapps/download/AutoDL?BundleId=245038_d3c52aa6bfa54d3ca74e617f18309292"
wget -O $RUNNER_TEMP/java_package.tar.gz $download_url
- uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
- uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: 'jdkfile'
jdkFile: ${{ runner.temp }}/java_package.tar.gz
@@ -92,7 +92,7 @@ jobs:
- name: Run Tests
run: mvn --batch-mode --no-transfer-progress test
- name: Publish Test Report
uses: mikepenz/action-junit-report@e08919a3b1fb83a78393dfb775a9c37f17d8eea6 # v5
uses: mikepenz/action-junit-report@74626db7353a25a20a72816467ebf035f674c5f8 # v5
if: ${{ !cancelled() }}
with:
report_paths: "**/target/surefire-reports/TEST*.xml"
@@ -105,9 +105,9 @@ jobs:
if: github.ref == 'refs/heads/master' # only perform on latest master
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Maven Central
uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with: # running setup-java again overwrites the settings.xml
distribution: 'temurin'
java-version: '8'
+4 -4
View File
@@ -33,11 +33,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # v4.31.4
uses: github/codeql-action/init@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -51,7 +51,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # v4.31.4
uses: github/codeql-action/autobuild@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -64,6 +64,6 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # v4.31.4
uses: github/codeql-action/analyze@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2
with:
category: "/language:${{matrix.language}}"
+2 -2
View File
@@ -26,7 +26,7 @@ jobs:
steps:
- name: "Checkout code"
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
@@ -57,6 +57,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@e12f0178983d466f2f6028f5cc7a6d786fd97f4b # v4.31.4
uses: github/codeql-action/upload-sarif@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2
with:
sarif_file: results.sarif
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>com.twelvemonkeys</groupId>
<artifactId>twelvemonkeys</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<groupId>com.twelvemonkeys.bom</groupId>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.common</groupId>
<artifactId>common</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>common-image</artifactId>
<packaging>jar</packaging>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.common</groupId>
<artifactId>common</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>common-io</artifactId>
<packaging>jar</packaging>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.common</groupId>
<artifactId>common</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>common-lang</artifactId>
<packaging>jar</packaging>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys</groupId>
<artifactId>twelvemonkeys</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<groupId>com.twelvemonkeys.common</groupId>
<artifactId>common</artifactId>
@@ -21,7 +21,7 @@
</modules>
<properties>
<junit.jupiter.version>5.14.1</junit.jupiter.version>
<junit.jupiter.version>5.14.2</junit.jupiter.version>
</properties>
<dependencyManagement>
+2 -2
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys</groupId>
<artifactId>twelvemonkeys</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<groupId>com.twelvemonkeys.contrib</groupId>
<artifactId>contrib</artifactId>
@@ -14,7 +14,7 @@
</description>
<properties>
<junit.jupiter.version>5.14.1</junit.jupiter.version>
<junit.jupiter.version>5.14.2</junit.jupiter.version>
</properties>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-batik</artifactId>
<name>TwelveMonkeys :: ImageIO :: Batik Plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-bmp</artifactId>
<name>TwelveMonkeys :: ImageIO :: BMP plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-clippath</artifactId>
<name>TwelveMonkeys :: ImageIO :: Photoshop Path Support</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-core</artifactId>
<name>TwelveMonkeys :: ImageIO :: Core</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-dds</artifactId>
<name>TwelveMonkeys :: ImageIO :: DDS plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-hdr</artifactId>
<name>TwelveMonkeys :: ImageIO :: HDR plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-icns</artifactId>
<name>TwelveMonkeys :: ImageIO :: ICNS plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-iff</artifactId>
<name>TwelveMonkeys :: ImageIO :: IFF plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-jpeg-jai-interop</artifactId>
<name>TwelveMonkeys :: ImageIO :: JPEG/JAI TIFF Interop</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-jpeg-jep262-interop</artifactId>
<name>TwelveMonkeys :: ImageIO :: JPEG/JEP-262 Interop</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-jpeg</artifactId>
<name>TwelveMonkeys :: ImageIO :: JPEG plugin</name>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>imageio-metadata</artifactId>
@@ -41,7 +41,11 @@ import javax.imageio.stream.ImageOutputStream;
import java.io.IOException;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static com.twelvemonkeys.imageio.metadata.tiff.TIFFEntry.getType;
import static com.twelvemonkeys.imageio.metadata.tiff.TIFFEntry.getValueLength;
@@ -176,7 +180,7 @@ public final class TIFFWriter extends MetadataWriter {
stream.seek(dataOffset);
Directory subIFD = (Directory) value;
writeIFD(subIFD, stream, true);
dataOffset += computeDataSize(subIFD);
dataOffset += computeDataSize(subIFD) + directoryCountLength + subIFD.size() * entryLength;
stream.seek(streamPosition);
}
else {
@@ -30,14 +30,23 @@
package com.twelvemonkeys.imageio.metadata.tiff;
import com.twelvemonkeys.imageio.metadata.*;
import com.twelvemonkeys.imageio.metadata.AbstractDirectory;
import com.twelvemonkeys.imageio.metadata.AbstractEntry;
import com.twelvemonkeys.imageio.metadata.CompoundDirectory;
import com.twelvemonkeys.imageio.metadata.Directory;
import com.twelvemonkeys.imageio.metadata.Entry;
import com.twelvemonkeys.imageio.metadata.MetadataWriterAbstractTest;
import com.twelvemonkeys.imageio.metadata.exif.EXIF;
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStream;
import com.twelvemonkeys.io.FastByteArrayOutputStream;
import org.junit.jupiter.api.Test;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import javax.imageio.stream.ImageOutputStreamImpl;
import javax.imageio.stream.MemoryCacheImageOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -46,8 +55,10 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
/**
* TIFFWriterTest
@@ -272,7 +283,7 @@ public class TIFFWriterTest extends MetadataWriterAbstractTest {
Directory read = new TIFFReader().read(new ByteArrayImageInputStream(data));
assertNotNull(read.getEntryById(TIFF.TAG_SOFTWARE));
assertTrue(read.getEntryById(TIFF.TAG_SOFTWARE).getValue() instanceof String[], "value not an string array");
assertInstanceOf(String[].class, read.getEntryById(TIFF.TAG_SOFTWARE).getValue(), "value not an string array");
assertArrayEquals(strings, (String[]) read.getEntryById(TIFF.TAG_SOFTWARE).getValue());
}
@@ -285,7 +296,7 @@ public class TIFFWriterTest extends MetadataWriterAbstractTest {
TIFFEntry subSubIFD = new TIFFEntry(TIFF.TAG_SUB_IFD, TIFF.TYPE_LONG, new IFD(Collections.singletonList(subSubSubIFD)));
TIFFEntry subIFD = new TIFFEntry(TIFF.TAG_SUB_IFD, TIFF.TYPE_LONG, new IFD(Collections.singletonList(subSubIFD)));
List<Entry> entries = Collections.<Entry>singletonList(subIFD);
List<Entry> entries = Collections.singletonList(subIFD);
TIFFWriter writer = createWriter();
@@ -296,24 +307,67 @@ public class TIFFWriterTest extends MetadataWriterAbstractTest {
assertEquals(96, stream.getStreamPosition()); // 96 = 4 + 5 * (2 + 12) + 22
}
private static class NullImageOutputStream extends ImageOutputStreamImpl {
@Test
void testWriteNestedExifIFD() throws IOException {
String expectedUserComment = "This ia the expected user comment";
String expectedDateTime = "2026:01:01 00:00:01";
List<Entry> entries = new ArrayList<>();
List<Entry> subDirectoryEntries = new ArrayList<>();
subDirectoryEntries.add(new TIFFEntry(EXIF.TAG_USER_COMMENT, TIFF.TYPE_ASCII, expectedUserComment));
entries.add(new TIFFEntry(TIFF.TAG_DATE_TIME, expectedDateTime));
entries.add(new TIFFEntry(TIFF.TAG_EXIF_IFD, TIFF.TYPE_IFD, new IFD(subDirectoryEntries)));
// NOTE! For the test, it is important that this tag is > Exif IFD and inside IDF0 (even if this is an Exif tag)
entries.add(new TIFFEntry(EXIF.TAG_DATE_TIME_ORIGINAL, TIFF.TYPE_ASCII, expectedDateTime));
IFD expectedSub = new IFD(subDirectoryEntries);
IFD expected = new IFD(entries);
try (ByteArrayOutputStream bytes = new ByteArrayOutputStream()) {
// Write the TIFF w/Exif sub IFD
try (ImageOutputStream stream = new MemoryCacheImageOutputStream(bytes)) {
new TIFFWriter().write(expected, stream);
}
try (ImageInputStream stream = new ByteArrayImageInputStream(bytes.toByteArray())) {
// Read the TIFF back, and compare content
Directory directory = new TIFFReader().read(stream);
Entry dateTimeEntry = directory.getEntryById(EXIF.TAG_DATE_TIME_ORIGINAL);
assertNotNull(dateTimeEntry);
assertEquals(expectedDateTime, dateTimeEntry.getValue());
Entry exifEntry = directory.getEntryById(TIFF.TAG_EXIF_IFD);
IFD exifIFD = (IFD) exifEntry.getValue();
Entry userCommentEntry = exifIFD.getEntryById(EXIF.TAG_USER_COMMENT);
assertNotNull(userCommentEntry);
assertEquals(expectedUserComment, userCommentEntry.getValue());
assertEquals(expectedSub, exifIFD);
assertEquals(expected, ((CompoundDirectory) directory).getDirectory(0));
}
}
}
private static final class NullImageOutputStream extends ImageOutputStreamImpl {
@Override
public void write(int b) throws IOException {
public void write(int b) {
streamPos++;
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
public void write(byte[] b, int off, int len) {
streamPos += len;
}
@Override
public int read() throws IOException {
public int read() {
throw new UnsupportedOperationException("Method read not implemented");
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
public int read(byte[] b, int off, int len) {
throw new UnsupportedOperationException("Method read not implemented");
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-pcx</artifactId>
<name>TwelveMonkeys :: ImageIO :: PCX plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-pdf</artifactId>
<name>TwelveMonkeys :: ImageIO :: PDF plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-pict</artifactId>
<name>TwelveMonkeys :: ImageIO :: PICT plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-pnm</artifactId>
<name>TwelveMonkeys :: ImageIO :: PNM plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-psd</artifactId>
<name>TwelveMonkeys :: ImageIO :: PSD plugin</name>
@@ -410,9 +410,9 @@ public final class PSDMetadata extends AbstractMetadata {
if ((psdLayerInfo.blendMode.flags & 0x01) != 0) {
node.setAttribute("transparencyProtected", "true");
}
if ((psdLayerInfo.blendMode.flags & 0x02) != 0) {
node.setAttribute("visible", "true");
}
// Include always, to avoid ambiguity, as the flag is really "hidden", not "visible"...
boolean hidden = (psdLayerInfo.blendMode.flags & 0x02) != 0;
node.setAttribute("visible", hidden ? "false" : "true");
if ((psdLayerInfo.blendMode.flags & 0x04) != 0) {
node.setAttribute("obsolete", "true");
}
@@ -0,0 +1,119 @@
package com.twelvemonkeys.imageio.plugins.psd;
import static org.junit.jupiter.api.Assertions.*;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.spi.IIORegistry;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;
import org.junit.jupiter.api.Test;
import org.w3c.dom.NodeList;
import com.twelvemonkeys.imageio.stream.URLImageInputStreamSpi;
class PSDMetadataTest {
static {
IIORegistry.getDefaultInstance().registerServiceProvider(new URLImageInputStreamSpi());
ImageIO.setUseCache(false);
}
protected final PSDImageReaderSpi provider = createProvider();
private PSDImageReaderSpi createProvider() {
return new PSDImageReaderSpi();
}
private PSDImageReader createReader() throws IOException {
return (PSDImageReader) provider.createReaderInstance(null);
}
protected URL getClassLoaderResource(final String resource) {
return getClass().getResource(resource);
}
@Test
void testLayerInfo() throws IOException {
PSDImageReader imageReader = createReader();
try (ImageInputStream stream = ImageIO.createImageInputStream(getClassLoaderResource("/psd/photoshopping.psd"))) {
imageReader.setInput(stream);
IIOMetadata metadata = imageReader.getImageMetadata(0);
IIOMetadataNode root = (IIOMetadataNode) metadata.getAsTree(PSDMetadata.NATIVE_METADATA_FORMAT_NAME);
NodeList layerInfos = root.getElementsByTagName("LayerInfo");
assertEquals(5, layerInfos.getLength()); // Sanity
IIOMetadataNode layer1Info = (IIOMetadataNode) layerInfos.item(0);
assertEquals("Layer 1", layer1Info.getAttribute("name"));
assertEquals("2", layer1Info.getAttribute("layerId"));
assertEquals("0", layer1Info.getAttribute("top"));
assertEquals("0", layer1Info.getAttribute("left"));
assertEquals("225", layer1Info.getAttribute("bottom"));
assertEquals("300", layer1Info.getAttribute("right"));
assertEquals("norm", layer1Info.getAttribute("blendMode"));
assertEquals("255", layer1Info.getAttribute("opacity"));
assertEquals("base", layer1Info.getAttribute("clipping"));
assertEquals("true", layer1Info.getAttribute("visible"));
assertEquals("8", layer1Info.getAttribute("flags"));
IIOMetadataNode layer2Info = (IIOMetadataNode) layerInfos.item(1);
assertEquals("Layer 0 copy", layer2Info.getAttribute("name"));
assertEquals("11", layer2Info.getAttribute("layerId"));
assertEquals("0", layer2Info.getAttribute("top"));
assertEquals("0", layer2Info.getAttribute("left"));
assertEquals("225", layer2Info.getAttribute("bottom"));
assertEquals("300", layer2Info.getAttribute("right"));
assertEquals("norm", layer2Info.getAttribute("blendMode"));
assertEquals("255", layer2Info.getAttribute("opacity"));
assertEquals("base", layer2Info.getAttribute("clipping"));
assertEquals("true", layer2Info.getAttribute("visible"));
assertEquals("8", layer2Info.getAttribute("flags"));
IIOMetadataNode layer3Info = (IIOMetadataNode) layerInfos.item(2);
assertEquals("Layer 0 copy 2", layer3Info.getAttribute("name"));
assertEquals("12", layer3Info.getAttribute("layerId"));
assertEquals("0", layer3Info.getAttribute("top"));
assertEquals("0", layer3Info.getAttribute("left"));
assertEquals("225", layer3Info.getAttribute("bottom"));
assertEquals("159", layer3Info.getAttribute("right"));
assertEquals("norm", layer3Info.getAttribute("blendMode"));
assertEquals("255", layer3Info.getAttribute("opacity"));
assertEquals("base", layer3Info.getAttribute("clipping"));
assertEquals("true", layer3Info.getAttribute("visible"));
assertEquals("8", layer3Info.getAttribute("flags"));
IIOMetadataNode layer4Info = (IIOMetadataNode) layerInfos.item(3);
assertEquals("Layer 0 copy 3", layer4Info.getAttribute("name"));
assertEquals("13", layer4Info.getAttribute("layerId"));
assertEquals("0", layer4Info.getAttribute("top"));
assertEquals("0", layer4Info.getAttribute("left"));
assertEquals("225", layer4Info.getAttribute("bottom"));
assertEquals("300", layer4Info.getAttribute("right"));
assertEquals("norm", layer4Info.getAttribute("blendMode"));
assertEquals("255", layer4Info.getAttribute("opacity"));
assertEquals("base", layer4Info.getAttribute("clipping"));
assertEquals("false", layer4Info.getAttribute("visible"));
assertEquals("10", layer4Info.getAttribute("flags"));
IIOMetadataNode layer5Info = (IIOMetadataNode) layerInfos.item(4);
assertEquals("Layer 0", layer5Info.getAttribute("name"));
assertEquals("3", layer5Info.getAttribute("layerId"));
assertEquals("0", layer5Info.getAttribute("top"));
assertEquals("0", layer5Info.getAttribute("left"));
assertEquals("225", layer5Info.getAttribute("bottom"));
assertEquals("300", layer5Info.getAttribute("right"));
assertEquals("norm", layer5Info.getAttribute("blendMode"));
assertEquals("255", layer5Info.getAttribute("opacity"));
assertEquals("base", layer5Info.getAttribute("clipping"));
assertEquals("false", layer5Info.getAttribute("visible"));
assertEquals("10", layer5Info.getAttribute("flags"));
}
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-reference</artifactId>
<name>TwelveMonkeys :: ImageIO :: JDK Reference Tests</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-sgi</artifactId>
<name>TwelveMonkeys :: ImageIO :: SGI plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-tga</artifactId>
<name>TwelveMonkeys :: ImageIO :: TGA plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-thumbsdb</artifactId>
<name>TwelveMonkeys :: ImageIO :: Thumbs.db plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-tiff-jai-interop</artifactId>
<name>TwelveMonkeys :: ImageIO :: TIFF/JAI Metadata Interop</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-tiff-jdk-interop</artifactId>
<name>TwelveMonkeys :: ImageIO :: TIFF/JDK JPEG Interop</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-tiff</artifactId>
<name>TwelveMonkeys :: ImageIO :: TIFF plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-webp</artifactId>
<name>TwelveMonkeys :: ImageIO :: WebP plugin</name>
@@ -565,7 +565,7 @@ final class WebPImageReader extends ImageReaderBase {
readVP8Lossless(tempRaster, null, width, height);
// Copy from green (band 1) in temp to alpha in destination
WritableRaster alphaChannel = tempRaster.createWritableChild(0, 0, tempRaster.getWidth(), tempRaster.getHeight(), 0, 0, new int[]{1});
WritableRaster alphaChannel = tempRaster.createWritableChild(0, 0, width, height, 0, 0, new int[]{1});
alphaFilter(alphaChannel, filtering);
copyIntoRasterWithParams(alphaChannel, alphaRaster, param);
break;
@@ -166,73 +166,81 @@ final class HuffmanTable {
if (numPosCodeLens == 1) {
// Length is 0 so mask to clear length bits
Arrays.fill(level1, lengthsAndSymbols[0] & 0xffff);
return;
}
// Due to the layout of the elements this effectively first sorts by length and then symbol.
Arrays.sort(lengthsAndSymbols);
int[] count = new int[16];
for (int lengthAndSymbol : lengthsAndSymbols) {
count[lengthAndSymbol >>> 16]++;
}
// The next code, in the bit order it would appear on the input stream, i.e. it is reversed.
// Only the lowest bits (corresponding to the bit length of the code) are considered.
// Example: code 0..010 (length 2) would appear as 0..001.
int code = 0;
int step = 2;
index = 0;
// Used for level2 lookup
for (int length = 1; length <= LEVEL1_BITS; length++, step <<= 1) {
for (; count[length] > 0; count[length]--) {
int lengthAndSymbol = lengthsAndSymbols[index++];
for (int j = code; j < level1.length; j += step) {
level1[j] = lengthAndSymbol;
}
code = nextCode(code, length);
}
}
int rootMask = (1 << LEVEL1_BITS) - 1;
int rootEntry = -1;
int[] currentTable = null;
for (int i = 0; i < lengthsAndSymbols.length; i++) {
int lengthAndSymbol = lengthsAndSymbols[i];
step = 2;
for (int length = LEVEL1_BITS + 1; length <= 15; length++, step <<= 1) {
for (; count[length] > 0; count[length]--) {
int lengthAndSymbol = lengthsAndSymbols[index++];
int length = lengthAndSymbol >>> 16;
if ((code & rootMask) != rootEntry) {
int level2Bits = nextTableBitSize(count, length, LEVEL1_BITS);
int level2Size = 1 << level2Bits;
if (length <= LEVEL1_BITS) {
for (int j = code; j < level1.length; j += 1 << length) {
level1[j] = lengthAndSymbol;
}
}
else {
// Existing level2 table not fitting
if ((code & ((1 << LEVEL1_BITS) - 1)) != rootEntry) {
// Figure out needed table size.
// Start at current symbol and length.
// Every symbol uses 1 slot at the current bit length.
// Going up 1 bit in length multiplies the slots by 2.
// No more open slots indicate the table size to be big enough.
int maxLength = length;
for (int j = i, openSlots = 1 << (length - LEVEL1_BITS);
j < lengthsAndSymbols.length && openSlots > 0;
j++, openSlots--) {
int innerLength = lengthsAndSymbols[j] >>> 16;
while (innerLength != maxLength) {
maxLength++;
openSlots <<= 1;
}
}
int level2Size = maxLength - LEVEL1_BITS;
currentTable = new int[1 << level2Size];
rootEntry = code & ((1 << LEVEL1_BITS) - 1);
currentTable = new int[level2Size];
rootEntry = code & rootMask;
level2.add(currentTable);
// Set root table indirection
level1[rootEntry] = (LEVEL1_BITS + level2Size) << 16 | (level2.size() - 1);
level1[rootEntry] = (LEVEL1_BITS + level2Bits) << 16 | (level2.size() - 1);
}
// Add to existing (or newly generated) 2nd level table
for (int j = (code >>> LEVEL1_BITS); j < currentTable.length; j += 1 << (length - LEVEL1_BITS)) {
currentTable[j] = (length - LEVEL1_BITS) << 16 | (lengthAndSymbol & 0xffff);
int value = (length - LEVEL1_BITS) << 16 | (lengthAndSymbol & 0xffff);
for (int j = (code >>> LEVEL1_BITS); j < currentTable.length; j += step) {
currentTable[j] = value;
}
code = nextCode(code, length);
}
code = nextCode(code, length);
}
}
private static int nextTableBitSize(int[] count, int length, int rootBits) {
int left = 1 << (length - rootBits);
while (length < 15) {
left -= count[length];
if (left <= 0) {
break;
}
length++;
left <<= 1;
}
return length - rootBits;
}
/**
* Computes the next code
*
@@ -276,6 +276,12 @@ public final class VP8LDecoder {
private int decodeBwRef(WritableRaster raster, ColorCache colorCache, int width, HuffmanCodeGroup curCodeGroup, byte[] rgba, short code, int x, int y) throws IOException {
int length = lz77decode(code - 256);
int remaining = width * raster.getHeight() - (y * width + x);
if (length > remaining) {
throw new IIOException("Corrupt WebP stream, backward reference exceeds image bounds: length=" + length +
", remaining=" + remaining + ", x=" + x + ", y=" + y);
}
short distancePrefix = curCodeGroup.distanceCode.readSymbol(lsbBitReader);
int distanceCode = lz77decode(distancePrefix);
@@ -302,6 +308,11 @@ public final class VP8LDecoder {
ySrc++;
}
if (ySrc < 0 || ySrc >= raster.getHeight()) {
throw new IIOException("Corrupt WebP stream, backward reference outside image: distance=" + distanceCode +
", x=" + x + ", y=" + y + ", xSrc=" + xSrc + ", ySrc=" + ySrc);
}
for (int l = length; l > 0; x++, l--) {
// Check length and xSrc, ySrc not falling outside raster? (Should not occur if image is correct)
if (x == width) {
@@ -1,3 +1,4 @@
package com.twelvemonkeys.imageio.plugins.webp;
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
@@ -11,6 +12,8 @@ import javax.imageio.stream.MemoryCacheImageInputStream;
import java.awt.*;
import java.awt.image.*;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import static java.util.Arrays.asList;
@@ -266,4 +269,76 @@ public class WebPImageReaderTest extends ImageReaderAbstractTest<WebPImageReader
reader.dispose();
}
}
/**
* This test compares alpha channel information that is decoded by the WebPImageReader with the known "good" alpha
* channel information. To generate the known "good" alpha channel information, we use the command line and libwebp,
* e.g.
*
* <pre>{@code
* dwebp imageio/imageio-webp/src/test/resources/webp/lossless.transparent.webp -o /tmp/lossless.transparent.png
* magick /tmp/lossless.transparent.png -alpha extract -depth 8 gray:/tmp/lossless.transparent-alpha.raw
* shasum -a 256 /tmp/lossless.transparent-alpha.raw
* }</pre>
*
* @throws IOException
*/
@Test
public void testReadWriteTransparentWebP() throws IOException {
WebPImageReader reader = createReader();
try (ImageInputStream stream = ImageIO.createImageInputStream(getClassLoaderResource("/webp/lossless.transparent.webp"))) {
reader.setInput(stream);
// Read dimensions
int width = reader.getWidth(0);
int height = reader.getHeight(0);
assertEquals(1920, width, "Expected width of 1920");
assertEquals(1477, height, "Expected height of 1477");
// Read the full image and validate alpha output (exercises long LZ77 back-references).
BufferedImage image = reader.read(0);
assertNotNull(image, "Image should not be null");
assertEquals(width, image.getWidth(), "Image width should match");
assertEquals(height, image.getHeight(), "Image height should match");
assertTrue(image.getColorModel().hasAlpha(), "Image should have alpha channel");
assertEquals("79ffff20392a9cef308b317cbac9d3e57f78e26a4f49fb38b3f3b4dbc4e63c50",
sha256Alpha(image), "Alpha plane hash mismatch");
}
finally {
reader.dispose();
}
}
private static String sha256Alpha(BufferedImage image) {
WritableRaster alphaRaster = image.getAlphaRaster();
assertNotNull(alphaRaster, "Image should have alpha raster");
int width = alphaRaster.getWidth();
int height = alphaRaster.getHeight();
int[] samples = alphaRaster.getSamples(0, 0, width, height, 0, (int[]) null);
MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-256");
}
catch (NoSuchAlgorithmException e) {
throw new AssertionError("SHA-256 not available", e);
}
for (int sample : samples) {
digest.update((byte) sample);
}
return toHex(digest.digest());
}
private static String toHex(byte[] bytes) {
StringBuilder builder = new StringBuilder(bytes.length * 2);
for (byte b : bytes) {
builder.append(Character.forDigit((b >>> 4) & 0x0f, 16));
builder.append(Character.forDigit(b & 0x0f, 16));
}
return builder.toString();
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<artifactId>imageio-xwd</artifactId>
<name>TwelveMonkeys :: ImageIO :: XWD plugin</name>
+2 -2
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>com.twelvemonkeys</groupId>
<artifactId>twelvemonkeys</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.twelvemonkeys.imageio</groupId>
@@ -61,7 +61,7 @@
</modules>
<properties>
<junit.jupiter.version>5.14.1</junit.jupiter.version>
<junit.jupiter.version>5.14.2</junit.jupiter.version>
</properties>
<dependencies>
+4 -4
View File
@@ -4,7 +4,7 @@
<groupId>com.twelvemonkeys</groupId>
<artifactId>twelvemonkeys</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
<packaging>pom</packaging>
<name>TwelveMonkeys</name>
<description>TwelveMonkeys parent POM</description>
@@ -80,7 +80,7 @@
<connection>scm:git:https://github.com/haraldk/TwelveMonkeys</connection>
<developerConnection>scm:git:ssh://git@github.com/haraldk/TwelveMonkeys</developerConnection>
<url>https://github.com/haraldk/TwelveMonkeys</url>
<tag>twelvemonkeys-3.13.0</tag>
<tag>twelvemonkeys-3.13.1</tag>
</scm>
<distributionManagement>
@@ -176,7 +176,7 @@
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.7.0</version>
<version>0.10.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>central</publishingServerId>
@@ -250,7 +250,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.1</version>
<version>3.15.0</version>
<inherited>true</inherited>
<configuration>
<source>8</source>
+2 -2
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>com.twelvemonkeys</groupId>
<artifactId>twelvemonkeys</artifactId>
<version>3.13.0</version>
<version>3.13.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -15,7 +15,7 @@
</description>
<properties>
<junit.jupiter.version>5.14.1</junit.jupiter.version>
<junit.jupiter.version>5.14.2</junit.jupiter.version>
</properties>
<dependencies>