[Git][java-team/libthumbnailator-java][upstream] New upstream version 0.4.19

Markus Koschany (@apo) gitlab at salsa.debian.org
Mon Jan 23 20:11:17 GMT 2023



Markus Koschany pushed to branch upstream at Debian Java Maintainers / libthumbnailator-java


Commits:
3a356645 by Markus Koschany at 2023-01-23T21:07:16+01:00
New upstream version 0.4.19
- - - - -


7 changed files:

- README.md
- pom.xml
- src/main/java/net/coobird/thumbnailator/tasks/io/InputStreamImageSource.java
- + src/main/java/net/coobird/thumbnailator/util/Configurations.java
- + src/test/java/net/coobird/thumbnailator/util/ConfigurationsTest.java
- + src/test/resources/Configurations/all_false.txt
- + src/test/resources/Configurations/all_true.txt


Changes:

=====================================
README.md
=====================================
@@ -1,4 +1,4 @@
-_*October 23, 2022: Thumbnailator 0.4.18 has been released!
+_*December 31, 2022: Thumbnailator 0.4.19 has been released!
 See [Changes](https://github.com/coobird/thumbnailator/wiki/Changes) for details.*_
 
 _*Thumbnailator is now available through
@@ -49,7 +49,7 @@ The following pages have more information on what _Thumbnailator_ can do:
 
 * [Features](https://github.com/coobird/thumbnailator/wiki/Features)
 * [Examples](https://github.com/coobird/thumbnailator/wiki/Examples)
-* [Thumbnailator API Documentation](https://coobird.github.io/thumbnailator/javadoc/0.4.18/)
+* [Thumbnailator API Documentation](https://coobird.github.io/thumbnailator/javadoc/0.4.19/)
 * [Frequently Asked Questions](https://github.com/coobird/thumbnailator/wiki/FAQ)
 
 # Disclaimer


=====================================
pom.xml
=====================================
@@ -2,7 +2,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>net.coobird</groupId>
   <artifactId>thumbnailator</artifactId>
-  <version>0.4.18</version>
+  <version>0.4.19</version>
   <packaging>jar</packaging>
   <name>thumbnailator</name>
   <description>Thumbnailator - a thumbnail generation library for Java</description>
@@ -106,6 +106,7 @@
               <Implementation-Title>Thumbnailator</Implementation-Title>
               <Implementation-Version>${project.version}</Implementation-Version>
               <Implementation-Vendor>coobird.net</Implementation-Vendor>
+              <Automatic-Module-Name>net.coobird.thumbnailator</Automatic-Module-Name>
             </manifestEntries>
           </archive>
         </configuration>


=====================================
src/main/java/net/coobird/thumbnailator/tasks/io/InputStreamImageSource.java
=====================================
@@ -43,6 +43,7 @@ import net.coobird.thumbnailator.ThumbnailParameter;
 import net.coobird.thumbnailator.filters.ImageFilter;
 import net.coobird.thumbnailator.geometry.Region;
 import net.coobird.thumbnailator.tasks.UnsupportedFormatException;
+import net.coobird.thumbnailator.util.Configurations;
 import net.coobird.thumbnailator.util.exif.ExifFilterUtils;
 import net.coobird.thumbnailator.util.exif.ExifUtils;
 import net.coobird.thumbnailator.util.exif.Orientation;
@@ -81,7 +82,7 @@ public class InputStreamImageSource extends AbstractImageSource<InputStream> {
 			throw new NullPointerException("InputStream cannot be null.");
 		}
 
-		if (!Boolean.getBoolean("thumbnailator.disableExifWorkaround")) {
+		if (!Configurations.DISABLE_EXIF_WORKAROUND.getBoolean()) {
 			this.is = new ExifCaptureInputStream(is);
 		} else {
 			this.is = is;
@@ -173,8 +174,8 @@ public class InputStreamImageSource extends AbstractImageSource<InputStream> {
 		/**
 		 * A flag to indicate whether to output debug logs.
 		 */
-		private final boolean isDebug = Boolean.getBoolean("thumbnailator.debugLog.exifWorkaround")
-				|| Boolean.getBoolean("thumbnailator.debugLog");
+		private final boolean isDebug = Configurations.DEBUG_LOG_EXIF_WORKAROUND.getBoolean()
+				|| Configurations.DEBUG_LOG.getBoolean();
 
 		/**
 		 * Returns Exif data captured from the JPEG image.
@@ -542,7 +543,7 @@ public class InputStreamImageSource extends AbstractImageSource<InputStream> {
 		 * https://github.com/coobird/thumbnailator/issues/69
 		 */
 		if (param != null &&
-				Boolean.getBoolean("thumbnailator.conserveMemoryWorkaround") &&
+				Configurations.CONSERVE_MEMORY_WORKAROUND.getBoolean() &&
 				width > 1800 && height > 1800 &&
 				(width * height * 4L > Runtime.getRuntime().freeMemory() / 4)
 		) {


=====================================
src/main/java/net/coobird/thumbnailator/util/Configurations.java
=====================================
@@ -0,0 +1,150 @@
+package net.coobird.thumbnailator.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * This enum lists properties that affect the behavior of Thumbnailator.
+ * Most are used for enabling or disabling workarounds.
+ *
+ * <h2>Implementation note</h2>
+ * The values for properties listed here will be read from the system
+ * properties via {@link System#getProperty(String)}, therefore, can be set
+ * via the {@code -D} options when invoking the JVM.
+ * Alternatively, they can be included in {@code thumbnailator.properties}
+ * on the classpath (of the current thread's class loader.)
+ *
+ * <h2>Disclaimer</h2>
+ * Properties listed here are not part of Thumbnailator's public API.
+ * Therefore, code invoking Thumbnailator should not depend on these
+ * workarounds always being present.
+ */
+public enum Configurations {
+    /**
+     * Disables the Exif workaround.
+     * (<a href="https://github.com/coobird/thumbnailator/issues/108">Issue #108</a>)
+     * <br>
+     * Property name: {@code thumbnailator.disableExifWorkaround}
+     * <p>
+     * The default JPEG reader bundled with the JRE cannot handle JPEG images
+     * that doesn't have a JFIF APP0 marker segment as the first one.
+     * Some JPEG images have Exif (APP1) as the first one.
+     * <p>
+     * A workaround was introduced to resolve issue #108 by capturing the
+     * Exif data from the bitstream rather than relying on the JPEG reader.
+     * <p>
+     * Disabling this workaround will prevent Thumbnailator from properly
+     * identifying the image orientation of JPEG images which have Exif as
+     * the first marker.
+     * Therefore, unless the default behavior causes issues, disabling this
+     * workaround is not recommended.
+     */
+    DISABLE_EXIF_WORKAROUND("thumbnailator.disableExifWorkaround"),
+
+    /**
+     * Enable debug logging to standard error.
+     * This will enable debug logging throughout Thumbnailator.
+     * <br>
+     * Property name: {@code thumbnailator.debugLog}
+     */
+    DEBUG_LOG("thumbnailator.debugLog"),
+
+    /**
+     * Enable debug logging (to standard error) specifically for the
+     * {@link #DISABLE_EXIF_WORKAROUND Exif workaround}.
+     * <br>
+     * Property name: {@code thumbnailator.debugLog.exifWorkaround}
+     */
+    DEBUG_LOG_EXIF_WORKAROUND("thumbnailator.debugLog.exifWorkaround"),
+
+    /**
+     * Enable a workaround to conserve memory when handling large image files.
+     * (<a href="https://github.com/coobird/thumbnailator/issues/69">Issue #69</a>)
+     * <p>
+     * It is known that {@link OutOfMemoryError}s can occur when handling
+     * large images in Thumbnailator.
+     * <p>
+     * To fundamentally address the issue requires some dramatic design changes
+     * to the core parts of Thumbnailator which would take some time and would
+     * affect many internal parts of the library.
+     * Such changes would take time before being implemented, a workaround has
+     * been implemented in Thumbnailator 0.4.8 to reduce the likeliness of
+     * {@code OutOfMemoryError}s.
+     * <p>
+     * The workaround is not enabled by default, as it can negatively affect
+     * the quality of the final image. It has also not been extensively
+     * tested and will not necessarily prevent {@code OutOfMemoryError}s.
+     * <p>
+     * When the workaround enabled, a smaller version of the source image will
+     * be used to reduce memory usage, under the following conditions:
+     * <ul>
+     *   <li>Both height and width have dimensions larger than 1800 pixels</li>
+     *   <li>The expected memory size of the source image will take up more
+     *       than 1/4 of the available JVM free memory</li>
+     * </ul>
+     */
+    CONSERVE_MEMORY_WORKAROUND("thumbnailator.conserveMemoryWorkaround")
+    ;
+
+    private final String key;
+    private static final Properties properties;
+
+    static {
+        properties = new Properties();
+        init();
+    }
+
+    /**
+     * This method will initialize configurations from
+     * {@code thumbnailator.properties} on the classpath.
+     * <p>
+     * Implementation note: {@code thumbnailator.properties} is searched from
+     *                      the class loader associated with the current
+     *                      thread, rather than the system class loader.
+     * <p>
+     * This is intended only to be called from tests.
+     */
+    static void init() {
+        properties.clear();
+
+        InputStream resourceIs = Thread.currentThread()
+                .getContextClassLoader()
+                .getResourceAsStream("thumbnailator.properties");
+
+        if (resourceIs != null) {
+            try {
+                properties.load(resourceIs);
+                resourceIs.close();
+            } catch (IOException e) {
+                throw new RuntimeException("Error while reading thumbnailator.properties", e);
+            }
+        }
+    }
+
+    /**
+     * Clears the internal cache of properties.
+     * <p>
+     * This is intended only to be called from tests.
+     */
+    static void clear() {
+        properties.clear();
+    }
+
+    Configurations(String key) {
+        this.key = key;
+    }
+
+    /**
+     * Returns whether the specified configuration is enabled or not.
+     * @return  {@code true} if the configuration is enabled, {@code false}
+     *          otherwise.
+     */
+    public boolean getBoolean() {
+        String propertyValue = properties.getProperty(key);
+        if (propertyValue != null) {
+            return Boolean.parseBoolean(propertyValue);
+        }
+        return Boolean.getBoolean(key);
+    }
+}


=====================================
src/test/java/net/coobird/thumbnailator/util/ConfigurationsTest.java
=====================================
@@ -0,0 +1,104 @@
+package net.coobird.thumbnailator.util;
+
+import org.junit.*;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.RunWith;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.InitializationError;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+ at RunWith(Enclosed.class)
+public class ConfigurationsTest {
+
+    @Ignore
+    private static class Base {
+        @Before
+        public void resetConfiguration() {
+            Configurations.init();
+        }
+
+        @AfterClass
+        public static void clearConfiguration() {
+            Configurations.clear();
+        }
+    }
+
+    @RunWith(AllTruePropertiesTest.CustomRunner.class)
+    public static class AllTruePropertiesTest extends Base {
+        @Test
+        public void test() {
+            for (Configurations config : Configurations.values()) {
+                assertTrue(config.getBoolean());
+            }
+        }
+
+        public static class CustomRunner extends ThreadContextClassLoaderReplacingClassRunner {
+            public CustomRunner(Class<?> testClass) throws InitializationError {
+                super(testClass);
+            }
+
+            protected ClassLoader getCustomClassLoader() {
+                return new PropertiesFileRedirectingClassLoader("Configurations/all_true.txt");
+            }
+        }
+    }
+
+    @RunWith(AllFalsePropertiesTest.CustomRunner.class)
+    public static class AllFalsePropertiesTest extends Base {
+        @Test
+        public void test() {
+            for (Configurations config : Configurations.values()) {
+                assertFalse(config.getBoolean());
+            }
+        }
+
+        public static class CustomRunner extends ThreadContextClassLoaderReplacingClassRunner {
+            public CustomRunner(Class<?> testClass) throws InitializationError {
+                super(testClass);
+            }
+
+            protected ClassLoader getCustomClassLoader() {
+                return new PropertiesFileRedirectingClassLoader("Configurations/all_false.txt");
+            }
+        }
+    }
+
+    public abstract static class ThreadContextClassLoaderReplacingClassRunner extends BlockJUnit4ClassRunner {
+        public ThreadContextClassLoaderReplacingClassRunner(Class<?> testClass) throws InitializationError {
+            super(testClass);
+        }
+
+        protected abstract ClassLoader getCustomClassLoader();
+
+        @Override
+        public void run(RunNotifier notifier) {
+            Thread.currentThread().setContextClassLoader(getCustomClassLoader());
+            super.run(notifier);
+            Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
+        }
+    }
+
+    @Ignore
+    public static class PropertiesFileRedirectingClassLoader extends URLClassLoader {
+        private final String resourceForPropertiesFile;
+
+        public PropertiesFileRedirectingClassLoader(String resourceForPropertiesFile) {
+            super(new URL[] {});
+            this.resourceForPropertiesFile = resourceForPropertiesFile;
+        }
+
+        @Override
+        public URL getResource(String name) {
+            if (name.startsWith("thumbnailator.properties")) {
+                return ClassLoader.getSystemClassLoader().getResource(resourceForPropertiesFile);
+            }
+            return super.getResource(name);
+        }
+    }
+}


=====================================
src/test/resources/Configurations/all_false.txt
=====================================
@@ -0,0 +1,4 @@
+thumbnailator.disableExifWorkaround=false
+thumbnailator.debugLog=false
+thumbnailator.debugLog.exifWorkaround=false
+thumbnailator.conserveMemoryWorkaround=false
\ No newline at end of file


=====================================
src/test/resources/Configurations/all_true.txt
=====================================
@@ -0,0 +1,4 @@
+thumbnailator.disableExifWorkaround=true
+thumbnailator.debugLog=true
+thumbnailator.debugLog.exifWorkaround=true
+thumbnailator.conserveMemoryWorkaround=true
\ No newline at end of file



View it on GitLab: https://salsa.debian.org/java-team/libthumbnailator-java/-/commit/3a356645b976a4917491b4ca4b123870985c7a38

-- 
View it on GitLab: https://salsa.debian.org/java-team/libthumbnailator-java/-/commit/3a356645b976a4917491b4ca4b123870985c7a38
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20230123/8e882af9/attachment.htm>


More information about the pkg-java-commits mailing list