From 183b0cd4d2cdf86073dae912f54d6213d1269f0c Mon Sep 17 00:00:00 2001 From: Nicholas Smith Date: Thu, 29 Feb 2024 14:21:10 +0000 Subject: [PATCH 1/8] Now ensures all opened streams are closed --- .../com/drew/imaging/png/PngMetadataReader.java | 10 +++++----- Source/com/drew/lang/StreamUtil.java | 17 +++++++++-------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Source/com/drew/imaging/png/PngMetadataReader.java b/Source/com/drew/imaging/png/PngMetadataReader.java index c2dd8b9e9..2122e9ae9 100644 --- a/Source/com/drew/imaging/png/PngMetadataReader.java +++ b/Source/com/drew/imaging/png/PngMetadataReader.java @@ -177,10 +177,9 @@ private static void processChunk(@NotNull Metadata metadata, @NotNull PngChunk c int bytesLeft = bytes.length - (profileNameBytes.length + 1 + 1); byte[] compressedProfile = reader.getBytes(bytesLeft); - try { - InflaterInputStream inflateStream = new InflaterInputStream(new ByteArrayInputStream(compressedProfile)); + try (ByteArrayInputStream bais = new ByteArrayInputStream(compressedProfile); + InflaterInputStream inflateStream = new InflaterInputStream(bais)) { new IccReader().extract(new RandomAccessStreamReader(inflateStream), metadata, directory); - inflateStream.close(); } catch(java.util.zip.ZipException zex) { directory.addError(String.format("Exception decompressing PNG iCCP chunk : %s", zex.getMessage())); metadata.addDirectory(directory); @@ -222,8 +221,9 @@ private static void processChunk(@NotNull Metadata metadata, @NotNull PngChunk c int bytesLeft = bytes.length - (keywordsv.getBytes().length + 1 + 1); byte[] textBytes = null; if (compressionMethod == 0) { - try { - textBytes = StreamUtil.readAllBytes(new InflaterInputStream(new ByteArrayInputStream(bytes, bytes.length - bytesLeft, bytesLeft))); + try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes, bytes.length - bytesLeft, bytesLeft); + InflaterInputStream inflateStream = new InflaterInputStream(bais)) { + textBytes = StreamUtil.readAllBytes(inflateStream); } catch(java.util.zip.ZipException zex) { PngDirectory directory = new PngDirectory(PngChunkType.zTXt); directory.addError(String.format("Exception decompressing PNG zTXt chunk with keyword \"%s\": %s", keyword, zex.getMessage())); diff --git a/Source/com/drew/lang/StreamUtil.java b/Source/com/drew/lang/StreamUtil.java index 341b54b6e..38b7c875d 100644 --- a/Source/com/drew/lang/StreamUtil.java +++ b/Source/com/drew/lang/StreamUtil.java @@ -31,16 +31,17 @@ public final class StreamUtil { public static byte[] readAllBytes(InputStream stream) throws IOException { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + byte[] buffer = new byte[1024]; + while (true) { + int bytesRead = stream.read(buffer); + if (bytesRead == -1) + break; + outputStream.write(buffer, 0, bytesRead); + } - byte[] buffer = new byte[1024]; - while (true) { - int bytesRead = stream.read(buffer); - if (bytesRead == -1) - break; - outputStream.write(buffer, 0, bytesRead); + return outputStream.toByteArray(); } - return outputStream.toByteArray(); } } From 146c435ac86f271bf60f9745023b0d0162554382 Mon Sep 17 00:00:00 2001 From: Nicholas Smith Date: Thu, 29 Feb 2024 15:33:53 +0000 Subject: [PATCH 2/8] Trying to get GitHub actions to build this repo --- .ci.settings.xml | 11 +++ .github/workflows/ci-build.yml | 36 ++++++++ .github/workflows/ci-publish.yml | 44 ++++++++++ .github/workflows/maven.yml | 36 -------- metadata-extractor.iml | 20 +---- pom.xml | 138 +++++++++++++++++++++++-------- 6 files changed, 198 insertions(+), 87 deletions(-) create mode 100644 .ci.settings.xml create mode 100644 .github/workflows/ci-build.yml create mode 100644 .github/workflows/ci-publish.yml delete mode 100644 .github/workflows/maven.yml diff --git a/.ci.settings.xml b/.ci.settings.xml new file mode 100644 index 000000000..67264bf28 --- /dev/null +++ b/.ci.settings.xml @@ -0,0 +1,11 @@ + + + + + ossrh + ${env.SONATYPE_USERNAME} + ${env.SONATYPE_PASSWORD} + + + + diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml new file mode 100644 index 000000000..3534e0140 --- /dev/null +++ b/.github/workflows/ci-build.yml @@ -0,0 +1,36 @@ +name: 'CI Build' + +on: + workflow_dispatch: + push: + branches: + - master + pull_request: + types: [ opened, reopened, edited ] + branches: + - master + +concurrency: + group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}' + cancel-in-progress: false + +jobs: + compile-and-test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Java and Maven + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '8' + cache: 'maven' + cache-dependency-path: 'pom.xml' + + - name: Compile + run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V + + - name: Run tests + run: mvn test -B diff --git a/.github/workflows/ci-publish.yml b/.github/workflows/ci-publish.yml new file mode 100644 index 000000000..19e58fa0e --- /dev/null +++ b/.github/workflows/ci-publish.yml @@ -0,0 +1,44 @@ +name: 'CI Publish to Maven Central' + +on: + workflow_dispatch: + push: + tags: + - 'release/*' + +concurrency: + group: '${{ github.workflow }} @ ${{ github.head_ref || github.ref }}' + cancel-in-progress: false + +jobs: + compile-test-and-publish-to-maven-central: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Java and Maven + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '8' + cache: 'maven' + cache-dependency-path: 'pom.xml' + + - name: Compile + run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V + + - name: Run tests + run: mvn test -B + + - name: Copy publishing-config settings.xml into place + run: cp .ci.settings.xml $HOME/.m2/settings.xml + + - name: Publish to Maven Central + run: ./publish.sh + env: + SONATYPE_GPGKEY_FILE_ENCRYPTION_KEY: ${{ secrets.SONATYPE_GPGKEY_FILE_ENCRYPTION_KEY }} + SONATYPE_GPGKEY_FILE_ENCRYPTION_IV: ${{ secrets.SONATYPE_GPGKEY_FILE_ENCRYPTION_IV }} + SONATYPE_GPGKEY_PASSPHRASE: ${{ secrets.SONATYPE_GPGKEY_PASSPHRASE }} + SONATYPE_USERNAME: ${{ vars.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml deleted file mode 100644 index fdb69aaab..000000000 --- a/.github/workflows/maven.yml +++ /dev/null @@ -1,36 +0,0 @@ -# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven - -name: Java CI with Maven - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -jobs: - build: - - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - java: ['7', '8', '11', '17', '18'] - - steps: - - uses: actions/checkout@v3 - - name: Set up JDK 7 - if: ${{ matrix.java == '7'}} - uses: actions/setup-java@v1 - with: - java-version: ${{ matrix.java }} - - name: Set up JDK - if: ${{ matrix.java != '7'}} - uses: actions/setup-java@v3 - with: - java-version: ${{ matrix.java }} - distribution: temurin - cache: maven - - name: Build with Maven - run: mvn -B package -Dgpg.skip=true --file pom.xml diff --git a/metadata-extractor.iml b/metadata-extractor.iml index 64d8d9cca..2a4f693a7 100644 --- a/metadata-extractor.iml +++ b/metadata-extractor.iml @@ -1,20 +1,6 @@ - - - - - - - - - - - - - - - - - + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index d1d171aed..dc937b629 100644 --- a/pom.xml +++ b/pom.xml @@ -12,9 +12,9 @@ 7 - com.drewnoakes + com.github.dalet-oss metadata-extractor - 2.19.0 + ${revision} jar ${project.groupId}:${project.artifactId} @@ -47,9 +47,9 @@ - scm:git:git://github.com/drewnoakes/metadata-extractor.git - scm:git:git@github.com:drewnoakes/metadata-extractor.git - https://github.com/drewnoakes/metadata-extractor + scm:git:git://github.com/dalet-oss/metadata-extractor.git + scm:git:git@github.com:dalet-oss/metadata-extractor.git + https://github.com/dalet-oss/metadata-extractor @@ -61,6 +61,12 @@ + 1.8 + 1.8 + + false + + DEV UTF-8 @@ -88,6 +94,96 @@ -Xdoclint:none + + release + + + + org.codehaus.mojo + flatten-maven-plugin + 1.5.0 + + true + resolveCiFriendliesOnly + + + + flatten.clean + clean + + clean + + + + flatten + process-resources + + flatten + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.3.0 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.6.3 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 3.1.0 + + + sign-artifacts + verify + + sign + + + true + + --pinentry-mode + loopback + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.13 + true + + ossrh + https://s01.oss.sonatype.org/ + true + + + + + @@ -178,40 +274,14 @@ - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.8 - true - - ossrh - https://oss.sonatype.org/ - - false - - - + ossrh - https://oss.sonatype.org/content/repositories/snapshots - + https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ + From 154ce90b6ead5575c2c29c99adc437baa4847bae Mon Sep 17 00:00:00 2001 From: Nicholas Smith Date: Thu, 29 Feb 2024 15:39:23 +0000 Subject: [PATCH 3/8] Fixed another couple of unclosed streams --- Source/com/drew/imaging/png/PngMetadataReader.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/com/drew/imaging/png/PngMetadataReader.java b/Source/com/drew/imaging/png/PngMetadataReader.java index 2122e9ae9..e283ec90a 100644 --- a/Source/com/drew/imaging/png/PngMetadataReader.java +++ b/Source/com/drew/imaging/png/PngMetadataReader.java @@ -266,8 +266,9 @@ private static void processChunk(@NotNull Metadata metadata, @NotNull PngChunk c textBytes = reader.getNullTerminatedBytes(bytesLeft, false); } else if (compressionFlag == 1) { if (compressionMethod == 0) { - try { - textBytes = StreamUtil.readAllBytes(new InflaterInputStream(new ByteArrayInputStream(bytes, bytes.length - bytesLeft, bytesLeft))); + try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes, bytes.length - bytesLeft, bytesLeft); + InflaterInputStream inflateStream = new InflaterInputStream(bais)) { + textBytes = StreamUtil.readAllBytes(inflateStream); } catch(java.util.zip.ZipException zex) { PngDirectory directory = new PngDirectory(PngChunkType.iTXt); directory.addError(String.format("Exception decompressing PNG iTXt chunk with keyword \"%s\": %s", keyword, zex.getMessage())); From 18555953100b9861fd1b770f8c3ff11a3b7a8c45 Mon Sep 17 00:00:00 2001 From: Nicholas Smith Date: Thu, 29 Feb 2024 15:49:02 +0000 Subject: [PATCH 4/8] Added publish.sh --- publish.sh | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100755 publish.sh diff --git a/publish.sh b/publish.sh new file mode 100755 index 000000000..f459f3cf5 --- /dev/null +++ b/publish.sh @@ -0,0 +1,50 @@ +echo 'Determining version number for publication' +echo 'Looking for an existing release tag against this commit' + +VERSION=$(git describe --tags --match release/* --exact-match 2>&1) +if [ $? -ne 0 ] +then + LAST=$(git describe --tags --match release/* 2>&1) + if [ $? -ne 0 ] + then + echo 'No release tags found at all; bail out' + exit 1 + fi + + echo "No matching tag found. Push a tag like release/1.0.1 against HEAD in order to release. Most recent tag is: ${LAST}" + exit 0 +fi + +VERSION=$(echo $VERSION | sed 's#release/##g') +echo "Publishing version: ${VERSION}" + +status=$(curl -s --head -w %{http_code} -o /dev/null https://repo1.maven.org/maven2/com/github/dalet-oss/arangobee/${VERSION}/) +if [ $status -eq 200 ] +then + echo 'Version already available on Maven Central. This must be a rebuild; nothing to do here.' +else + echo 'Version not already available on Maven Central' + + # Decrypt the gpg key used for signing + echo 'Decrypting the GPG key used for signing' + openssl aes-256-cbc -K ${SONATYPE_GPGKEY_FILE_ENCRYPTION_KEY} -iv ${SONATYPE_GPGKEY_FILE_ENCRYPTION_IV} -in secret.gpg.enc -out secret.gpg -d + export GPG_TTY=$(tty) + if [ ! -f secret.gpg ] + then + echo 'Decryption failed; bail out' + exit 1 + fi + echo 'Decryption successful' + + # Work around some nonsense on the specific version of GPG that comes with Ubuntu - see https://www.fluidkeys.com/tweak-gpg-2.1.11/ + echo 'allow-loopback-pinentry' >> ~/.gnupg/gpg-agent.conf + gpgconf --reload gpg-agent + + # Add the key into gpg; then sign something random to get the key into the gpg-agent + echo ${SONATYPE_GPGKEY_PASSPHRASE} | gpg2 --passphrase-fd 0 --batch --yes --import secret.gpg + touch /tmp/foo.txt + gpg2 --pinentry-mode=loopback --passphrase ${SONATYPE_GPGKEY_PASSPHRASE} --sign /tmp/foo.txt + + # Build, sign and publish the artifacts + mvn -Prelease deploy -DskipTests -Drevision=${VERSION} -Dgpg.executable=gpg2 -Dgpgkey.passphrase=${SONATYPE_GPGKEY_PASSPHRASE} +fi From 996b039a94bd24765ef3b9fbbf11ec9cae147c0c Mon Sep 17 00:00:00 2001 From: Nicholas Smith Date: Thu, 29 Feb 2024 16:06:24 +0000 Subject: [PATCH 5/8] Added secret.gpg.enc --- secret.gpg.enc | Bin 0 -> 2640 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 secret.gpg.enc diff --git a/secret.gpg.enc b/secret.gpg.enc new file mode 100644 index 0000000000000000000000000000000000000000..fd1c131a3c998e8928e5c6ab8d2ee220f498a833 GIT binary patch literal 2640 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 Date: Thu, 29 Feb 2024 16:15:31 +0000 Subject: [PATCH 6/8] Trying to get Maven publishing working --- metadata-extractor.iml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata-extractor.iml b/metadata-extractor.iml index 2a4f693a7..0ca564a59 100644 --- a/metadata-extractor.iml +++ b/metadata-extractor.iml @@ -3,4 +3,4 @@ - \ No newline at end of file + From 89d13c2eb3b47c7679f1cf047b620b2527dddb9e Mon Sep 17 00:00:00 2001 From: Nicholas Smith Date: Thu, 29 Feb 2024 16:20:21 +0000 Subject: [PATCH 7/8] Trying to get Maven publishing working --- metadata-extractor.iml | 6 ------ pom.xml | 13 ------------- 2 files changed, 19 deletions(-) delete mode 100644 metadata-extractor.iml diff --git a/metadata-extractor.iml b/metadata-extractor.iml deleted file mode 100644 index 0ca564a59..000000000 --- a/metadata-extractor.iml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/pom.xml b/pom.xml index dc937b629..0d744a51c 100644 --- a/pom.xml +++ b/pom.xml @@ -123,19 +123,6 @@ - - org.apache.maven.plugins - maven-source-plugin - 3.3.0 - - - attach-sources - - jar-no-fork - - - - org.apache.maven.plugins maven-javadoc-plugin From 32f104d57fbb112f0424108b60ac93ed4593d328 Mon Sep 17 00:00:00 2001 From: Nick Smith Date: Tue, 5 Mar 2024 11:11:41 +0000 Subject: [PATCH 8/8] Found more streams to close --- .gitignore | 1 + .../com/drew/imaging/ImageMetadataReader.java | 16 +-- Source/com/drew/lang/StringUtil.java | 15 +-- Source/com/drew/metadata/eps/EpsReader.java | 98 ++++++++++--------- .../drew/metadata/exif/ExifTiffHandler.java | 5 +- Source/com/drew/metadata/gif/GifReader.java | 38 +++---- .../metadata/heif/HeifPictureHandler.java | 5 +- .../ProcessAllImagesInFolderUtility.java | 95 +++++++++--------- .../com/drew/lang/CompoundExceptionTest.java | 7 +- 9 files changed, 148 insertions(+), 132 deletions(-) diff --git a/.gitignore b/.gitignore index 6e30df54e..cf3a5c865 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ build .DS_Store .gradle +/metadata-extractor.iml diff --git a/Source/com/drew/imaging/ImageMetadataReader.java b/Source/com/drew/imaging/ImageMetadataReader.java index 474300950..7bdcd1098 100644 --- a/Source/com/drew/imaging/ImageMetadataReader.java +++ b/Source/com/drew/imaging/ImageMetadataReader.java @@ -115,17 +115,19 @@ public static Metadata readMetadata(@NotNull final InputStream inputStream) thro @NotNull public static Metadata readMetadata(@NotNull final InputStream inputStream, final long streamLength) throws ImageProcessingException, IOException { - BufferedInputStream bufferedInputStream = inputStream instanceof BufferedInputStream - ? (BufferedInputStream)inputStream - : new BufferedInputStream(inputStream); + try (BufferedInputStream bufferedInputStream = inputStream instanceof BufferedInputStream + ? (BufferedInputStream)inputStream : new BufferedInputStream(inputStream)) { - FileType fileType = FileTypeDetector.detectFileType(bufferedInputStream); + FileType fileType = FileTypeDetector.detectFileType(bufferedInputStream); - Metadata metadata = readMetadata(bufferedInputStream, streamLength, fileType); + Metadata metadata = readMetadata(bufferedInputStream, streamLength, fileType); - metadata.addDirectory(new FileTypeDirectory(fileType)); + metadata.addDirectory(new FileTypeDirectory(fileType)); + + return metadata; + + } - return metadata; } /** diff --git a/Source/com/drew/lang/StringUtil.java b/Source/com/drew/lang/StringUtil.java index 586d9ce86..be04906ec 100644 --- a/Source/com/drew/lang/StringUtil.java +++ b/Source/com/drew/lang/StringUtil.java @@ -81,15 +81,18 @@ public static String join(@NotNull T[] strings, @NotNul @NotNull public static String fromStream(@NotNull InputStream stream) throws IOException { - BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); - StringBuilder sb = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - sb.append(line); + try (InputStreamReader inputStreamReader = new InputStreamReader(stream); + BufferedReader reader = new BufferedReader(inputStreamReader)) { + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + return sb.toString(); } - return sb.toString(); } + public static int compare(@Nullable String s1, @Nullable String s2) { boolean null1 = s1 == null; diff --git a/Source/com/drew/metadata/eps/EpsReader.java b/Source/com/drew/metadata/eps/EpsReader.java index 24d8233c5..1e616b7a5 100644 --- a/Source/com/drew/metadata/eps/EpsReader.java +++ b/Source/com/drew/metadata/eps/EpsReader.java @@ -264,21 +264,22 @@ private static void extractXmpData(@NotNull final Metadata metadata, @NotNull Se */ private static byte[] readUntil(@NotNull SequentialReader reader, @NotNull byte[] sentinel) throws IOException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - - final int length = sentinel.length; - int depth = 0; - - while (depth != length) { - byte b = reader.getByte(); - if (b == sentinel[depth]) - depth++; - else - depth = 0; - bytes.write(b); + try (ByteArrayOutputStream bytes = new ByteArrayOutputStream()) { + final int length = sentinel.length; + int depth = 0; + + while (depth != length) { + byte b = reader.getByte(); + if (b == sentinel[depth]) + depth++; + else + depth = 0; + bytes.write(b); + } + + return bytes.toByteArray(); } - return bytes.toByteArray(); } /** @@ -303,48 +304,48 @@ private static byte[] readUntil(@NotNull SequentialReader reader, @NotNull byte[ @Nullable private static byte[] decodeHexCommentBlock(@NotNull SequentialReader reader) throws IOException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + try (ByteArrayOutputStream bytes = new ByteArrayOutputStream()) { - // Use a state machine to efficiently parse data in a single traversal + // Use a state machine to efficiently parse data in a single traversal - final int AwaitingPercent = 0; - final int AwaitingSpace = 1; - final int AwaitingHex1 = 2; - final int AwaitingHex2 = 3; + final int AwaitingPercent = 0; + final int AwaitingSpace = 1; + final int AwaitingHex1 = 2; + final int AwaitingHex2 = 3; - int state = AwaitingPercent; + int state = AwaitingPercent; - int carry = 0; - boolean done = false; + int carry = 0; + boolean done = false; - byte b = 0; - while (!done) { - b = reader.getByte(); + byte b = 0; + while (!done) { + b = reader.getByte(); - switch (state) { + switch (state) { case AwaitingPercent: { switch (b) { - case '\r': - case '\n': - case ' ': - // skip newline chars and spaces - break; - case '%': - state = AwaitingSpace; - break; - default: - return null; + case '\r': + case '\n': + case ' ': + // skip newline chars and spaces + break; + case '%': + state = AwaitingSpace; + break; + default: + return null; } break; } case AwaitingSpace: { switch (b) { - case ' ': - state = AwaitingHex1; - break; - default: - done = true; - break; + case ' ': + state = AwaitingHex1; + break; + default: + done = true; + break; } break; } @@ -368,14 +369,17 @@ private static byte[] decodeHexCommentBlock(@NotNull SequentialReader reader) th state = AwaitingHex1; break; } + } } - } - // skip through the remainder of the last line - while (b != '\n') - b = reader.getByte(); + // skip through the remainder of the last line + while (b != '\n') + b = reader.getByte(); + + return bytes.toByteArray(); + + } - return bytes.toByteArray(); } /** diff --git a/Source/com/drew/metadata/exif/ExifTiffHandler.java b/Source/com/drew/metadata/exif/ExifTiffHandler.java index 6189588f6..5bfc1e3e0 100644 --- a/Source/com/drew/metadata/exif/ExifTiffHandler.java +++ b/Source/com/drew/metadata/exif/ExifTiffHandler.java @@ -320,14 +320,15 @@ public boolean customProcessTag(final int tagOffset, byte[] jpegrawbytes = reader.getBytes(tagOffset, byteCount); // Extract information from embedded image since it is metadata-rich - ByteArrayInputStream jpegmem = new ByteArrayInputStream(jpegrawbytes); - try { + try (ByteArrayInputStream jpegmem = new ByteArrayInputStream(jpegrawbytes)) { + Metadata jpegDirectory = JpegMetadataReader.readMetadata(jpegmem); for (Directory directory : jpegDirectory.getDirectories()) { directory.setParent(_currentDirectory); _metadata.addDirectory(directory); } return true; + } catch (JpegProcessingException e) { _currentDirectory.addError("Error processing JpgFromRaw: " + e.getMessage()); } catch (IOException e) { diff --git a/Source/com/drew/metadata/gif/GifReader.java b/Source/com/drew/metadata/gif/GifReader.java index 32a1e8e74..1a6112e2a 100644 --- a/Source/com/drew/metadata/gif/GifReader.java +++ b/Source/com/drew/metadata/gif/GifReader.java @@ -356,37 +356,39 @@ private static GifImageDirectory readImageBlock(SequentialReader reader) throws private static byte[] gatherBytes(SequentialReader reader) throws IOException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - byte[] buffer = new byte[257]; + try (ByteArrayOutputStream bytes = new ByteArrayOutputStream()) { + byte[] buffer = new byte[257]; - while (true) - { - byte b = reader.getByte(); - if (b == 0) - return bytes.toByteArray(); + while (true) + { + byte b = reader.getByte(); + if (b == 0) + return bytes.toByteArray(); - int bInt = b & 0xFF; + int bInt = b & 0xFF; - buffer[0] = b; - reader.getBytes(buffer, 1, bInt); - bytes.write(buffer, 0, bInt + 1); + buffer[0] = b; + reader.getBytes(buffer, 1, bInt); + bytes.write(buffer, 0, bInt + 1); + } } } private static byte[] gatherBytes(SequentialReader reader, int firstLength) throws IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + try (ByteArrayOutputStream buffer = new ByteArrayOutputStream()) { + int length = firstLength; - int length = firstLength; + while (length > 0) + { + buffer.write(reader.getBytes(length), 0, length); - while (length > 0) - { - buffer.write(reader.getBytes(length), 0, length); + length = reader.getByte() & 0xff; + } - length = reader.getByte() & 0xff; + return buffer.toByteArray(); } - return buffer.toByteArray(); } private static void skipBlocks(SequentialReader reader) throws IOException diff --git a/Source/com/drew/metadata/heif/HeifPictureHandler.java b/Source/com/drew/metadata/heif/HeifPictureHandler.java index 088a9d636..5f9ff8650 100644 --- a/Source/com/drew/metadata/heif/HeifPictureHandler.java +++ b/Source/com/drew/metadata/heif/HeifPictureHandler.java @@ -150,8 +150,9 @@ private void handleItem(@NotNull ItemInfoBox.ItemInfoEntry entry, return; } payloadReader.skip(tiffHeaderOffset); - ByteArrayInputStream tiffStream = new ByteArrayInputStream(payloadReader.getBytes(payloadReader.available())); - new ExifReader().extract(new RandomAccessStreamReader(tiffStream), metadata); + try (ByteArrayInputStream tiffStream = new ByteArrayInputStream(payloadReader.getBytes(payloadReader.available()))) { + new ExifReader().extract(new RandomAccessStreamReader(tiffStream), metadata); + } } } diff --git a/Source/com/drew/tools/ProcessAllImagesInFolderUtility.java b/Source/com/drew/tools/ProcessAllImagesInFolderUtility.java index b9327b82b..49e44aba1 100644 --- a/Source/com/drew/tools/ProcessAllImagesInFolderUtility.java +++ b/Source/com/drew/tools/ProcessAllImagesInFolderUtility.java @@ -42,6 +42,7 @@ import com.drew.metadata.xmp.XmpDirectory; import java.io.*; +import java.nio.charset.StandardCharsets; import java.util.*; /** @@ -75,7 +76,11 @@ public static void main(String[] args) throws IOException printUsage(); System.exit(1); } - log = new PrintStream(new FileOutputStream(args[++i], false), true); + + try (FileOutputStream fos = new FileOutputStream(args[++i], false)) { + log = new PrintStream(fos , true); + } + } else { // Treat this argument as a directory directories.add(arg); @@ -492,26 +497,19 @@ private static PrintWriter openWriter(@NotNull File file) throws IOException javaDir.mkdir(); String outputPath = String.format("%s/metadata/java/%s.txt", file.getParent(), file.getName()); - Writer writer = new OutputStreamWriter( - new FileOutputStream(outputPath), - "UTF-8" - ); - writer.write("FILE: " + file.getName() + NEW_LINE); - - // Detect file type - BufferedInputStream stream = null; - try { - stream = new BufferedInputStream(new FileInputStream(file)); + try (FileOutputStream fos = new FileOutputStream(outputPath); + Writer writer = new OutputStreamWriter(fos, StandardCharsets.UTF_8); + FileInputStream fis =new FileInputStream(file); + BufferedInputStream stream = new BufferedInputStream(fis)) { + writer.write("FILE: " + file.getName() + NEW_LINE); + FileType fileType = FileTypeDetector.detectFileType(stream); writer.write(String.format("TYPE: %s" + NEW_LINE, fileType.toString().toUpperCase())); writer.write(NEW_LINE); - } finally { - if (stream != null) { - stream.close(); - } + + return new PrintWriter(writer); } - return new PrintWriter(writer); } private static void closeWriter(@Nullable Writer writer) throws IOException @@ -638,46 +636,49 @@ public void onScanCompleted(@NotNull PrintStream log) private void writeOutput(@NotNull PrintStream stream) throws IOException { - Writer writer = new OutputStreamWriter(stream); - writer.write("# Image Database Summary\n\n"); + try (Writer writer = new OutputStreamWriter(stream)) { - for (Map.Entry> entry : _rowListByExtension.entrySet()) { - String extension = entry.getKey(); - writer.write("## " + extension.toUpperCase() + " Files\n\n"); + writer.write("# Image Database Summary\n\n"); - writer.write("File|Manufacturer|Model|Dir Count|Exif?|Makernote|Thumbnail|All Data\n"); - writer.write("----|------------|-----|---------|-----|---------|---------|--------\n"); + for (Map.Entry> entry : _rowListByExtension.entrySet()) { + String extension = entry.getKey(); + writer.write("## " + extension.toUpperCase() + " Files\n\n"); - List rows = entry.getValue(); + writer.write("File|Manufacturer|Model|Dir Count|Exif?|Makernote|Thumbnail|All Data\n"); + writer.write("----|------------|-----|---------|-----|---------|---------|--------\n"); - // Order by manufacturer, then model - Collections.sort(rows, new Comparator() { - public int compare(Row o1, Row o2) - { - int c1 = StringUtil.compare(o1.manufacturer, o2.manufacturer); - return c1 != 0 ? c1 : StringUtil.compare(o1.model, o2.model); + List rows = entry.getValue(); + + // Order by manufacturer, then model + Collections.sort(rows, new Comparator() { + public int compare(Row o1, Row o2) + { + int c1 = StringUtil.compare(o1.manufacturer, o2.manufacturer); + return c1 != 0 ? c1 : StringUtil.compare(o1.model, o2.model); + } + }); + + for (Row row : rows) { + writer.write(String.format("[%s](https://raw.githubusercontent.com/drewnoakes/metadata-extractor-images/master/%s/%s)|%s|%s|%d|%s|%s|%s|[metadata](https://raw.githubusercontent.com/drewnoakes/metadata-extractor-images/master/%s/metadata/%s.txt)\n", + row.file.getName(), + row.relativePath, + StringUtil.urlEncode(row.file.getName()), + row.manufacturer == null ? "" : row.manufacturer, + row.model == null ? "" : row.model, + row.metadata.getDirectoryCount(), + row.exifVersion == null ? "" : row.exifVersion, + row.makernote == null ? "" : row.makernote, + row.thumbnail == null ? "" : row.thumbnail, + row.relativePath, + StringUtil.urlEncode(row.file.getName()).toLowerCase() + )); } - }); - for (Row row : rows) { - writer.write(String.format("[%s](https://raw.githubusercontent.com/drewnoakes/metadata-extractor-images/master/%s/%s)|%s|%s|%d|%s|%s|%s|[metadata](https://raw.githubusercontent.com/drewnoakes/metadata-extractor-images/master/%s/metadata/%s.txt)\n", - row.file.getName(), - row.relativePath, - StringUtil.urlEncode(row.file.getName()), - row.manufacturer == null ? "" : row.manufacturer, - row.model == null ? "" : row.model, - row.metadata.getDirectoryCount(), - row.exifVersion == null ? "" : row.exifVersion, - row.makernote == null ? "" : row.makernote, - row.thumbnail == null ? "" : row.thumbnail, - row.relativePath, - StringUtil.urlEncode(row.file.getName()).toLowerCase() - )); + writer.write('\n'); } + writer.flush(); - writer.write('\n'); } - writer.flush(); } } diff --git a/Tests/com/drew/lang/CompoundExceptionTest.java b/Tests/com/drew/lang/CompoundExceptionTest.java index f836d1767..3590178c9 100644 --- a/Tests/com/drew/lang/CompoundExceptionTest.java +++ b/Tests/com/drew/lang/CompoundExceptionTest.java @@ -68,10 +68,11 @@ public void testNoInnerException() throws Exception try { throw new CompoundException("message", null); } catch (CompoundException e) { - try { - PrintStream nullStream = new PrintStream(new NullOutputStream()); + try (NullOutputStream nullOutputStream = new NullOutputStream(); + PrintStream nullStream = new PrintStream(nullOutputStream); + PrintWriter printWriter = new PrintWriter(nullStream)) { e.printStackTrace(nullStream); - e.printStackTrace(new PrintWriter(nullStream)); + e.printStackTrace(printWriter); } catch (Exception e1) { fail("Exception during printStackTrace for CompoundException with no inner exception"); }