-
Notifications
You must be signed in to change notification settings - Fork 492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8306707: Support pluggable image loading via javax.imageio #1593
Conversation
👋 Welcome back mstrauss! A progress list of the required criteria for merging this PR into |
/reviewers 2 |
@mstr2 This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 1 new commit pushed to the
Please see this link for an up-to-date comparison between the source branch of this pull request and the ➡️ To integrate this PR with the above commit message to the |
Webrevs
|
/reviewers 2 reviewers |
@mstr2 has indicated that a compatibility and specification (CSR) request is needed for this pull request. @mstr2 please create a CSR request for issue JDK-8306707 with the correct fix version. This pull request cannot be integrated until the CSR request is approved. |
@kevinrushforth |
@kevinrushforth an approved CSR request is already required for this pull request. |
With the restructuring to make the dependency optional at runtime, this seems like a reasonable approach to consider. I also want to make sure that we don't initialize the AWT toolkit unless an application tries to load an image file of a format that JavaFX doesn't support. It will take some time to review and test it. |
It is at all possible to split the image loaders from the desktop module into its own? I would think it will be useful for more than just JavaFX. |
Any idea why FX has custom image loaders at all, and doesn't simply always delegate to |
I've used import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import javax.imageio.ImageIO;
public class ImageIOAWTTest {
public static void main(String[] args) throws Exception {
// Check if AWT classes are loaded before using ImageIO
boolean awtLoadedBefore = isClassLoaded("java.awt.Toolkit");
// Load an image using ImageIO (this should not trigger AWT initialization)
ImageIO.read(URI.create("https://picsum.photos/200/300").toURL());
// Check if AWT classes are loaded after using ImageIO
boolean awtLoadedAfter = isClassLoaded("java.awt.Toolkit");
System.out.println("AWT loaded before ImageIO: " + awtLoadedBefore);
System.out.println("AWT loaded after ImageIO: " + awtLoadedAfter);
}
// Method to check if a class is loaded by the ClassLoader
private static boolean isClassLoaded(String className) throws NoSuchMethodException, SecurityException, IllegalAccessException, InvocationTargetException {
java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass", new Class[] { String.class });
m.setAccessible(true);
ClassLoader cl = ClassLoader.getSystemClassLoader();
Object test1 = m.invoke(cl, className);
return test1 != null;
}
} It will require |
Just a general comment on other code in byte[] header = new byte[getMaxSignatureLength()];
try {
ImageTools.readFully(stream, header);
} catch (EOFException ignored) {
return null;
} This code will take the largest possible signature length for known registered types (ie. JPG, GIF, BMP, PNG) and load those bytes. But if one of these formats could store a tiny image that would be smaller than the largest signature, then that image can't be loaded as this code would throw EOF and not return a suitable loader... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left some comments.
modules/javafx.graphics/src/main/java/com/sun/javafx/iio/ImageStorage.java
Outdated
Show resolved
Hide resolved
modules/javafx.graphics/src/main/java/com/sun/javafx/iio/javax/XImageLoader.java
Outdated
Show resolved
Hide resolved
modules/javafx.graphics/src/main/java/com/sun/javafx/iio/javax/XImageLoader.java
Outdated
Show resolved
Hide resolved
modules/javafx.graphics/src/main/java/com/sun/javafx/iio/javax/XImageLoader.java
Outdated
Show resolved
Hide resolved
modules/javafx.graphics/src/main/java/com/sun/javafx/image/impl/IntRgb.java
Show resolved
Hide resolved
modules/javafx.graphics/src/main/java/com/sun/javafx/image/impl/IntRgb.java
Show resolved
Hide resolved
modules/javafx.graphics/src/main/java/com/sun/javafx/image/impl/IntBgr.java
Show resolved
Hide resolved
modules/javafx.graphics/src/main/java/com/sun/javafx/image/impl/IntBgr.java
Show resolved
Hide resolved
I think @mstr2 can use |
/integrate delegate |
@mstr2 Integration of this pull request has been delegated and may be completed by any project committer using the /integrate pull request command. |
@jayathirthrao @hjohn Please review the latest changes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, I will re-approve if you decide to apply my suggestion for the exception messages.
@@ -211,6 +211,21 @@ public static int[] computeDimensions(int sourceWidth, int sourceHeight, | |||
return new int[]{finalWidth, finalHeight}; | |||
} | |||
|
|||
public static void validateMaxDimensions(double width, double height, double scaleFactor) { | |||
if (width * scaleFactor > Integer.MAX_VALUE) { | |||
throw new IllegalArgumentException("Image width exceeds maximum value"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may want to include the values used to reach this conclusion here and with the other 2 exceptions; if these exceptions ever come up, that's the first thing a developer will likely want to know (which may be you if this is posted in an issue).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed as suggested.
Thanks, Jay, I was going to suggest the same as an option for this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All looks good. I'll reapprove if you decide to make the changes suggested by John.
I'll integrate it later this morning (Pacific time) if all is settled.
/integrate |
@kevinrushforth Pushed as commit 72af9e2. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
too late to the party, but
|
I'm sure there are other cases like this. Time for a clean-up ticket? |
nope, only this one (we've cleaned up the rest) |
This PR is an improved version of #1093.
JavaFX can load BMP, GIF, PNG, and JPEG images with its built-in image loaders. It has been a long-standing request to support more image formats, most notably (but not limited to) SVG. However, adding more built-in image loaders is a significant effort not only in creating the functionality, but also in maintaining the additional dependencies.
This will probably not happen any time soon, so we are left with three alternatives:
From these options, I think we should simply support existing Java APIs; both because it is the shortest and most realistic path forward, but also because I don't think it is sensible to bifurcate pluggable image loading in the Java ecosystem.
Of course, Java Image I/O is a part of the
java.desktop
module, which as of now, all JavaFX applications require. However, it has been noted in the previous PR that we shouldn't lock JavaFX into thejava.desktop
dependency even further.I've improved this PR to not permanently require the
java.desktop
dependency: if the module is present, then JavaFX will use Image I/O for image formats that it can't load with the built-in loaders; if the module is not present, only the built-in loaders are available.I have prepared a small sample application that showcases how the feature can be used to load SVG images in a JavaFX application: https://github.com/mstr2/jfx-imageio-sample
Progress
Warning
Issues
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/1593/head:pull/1593
$ git checkout pull/1593
Update a local copy of the PR:
$ git checkout pull/1593
$ git pull https://git.openjdk.org/jfx.git pull/1593/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 1593
View PR using the GUI difftool:
$ git pr show -t 1593
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1593.diff
Using Webrev
Link to Webrev Comment