1717 *******************************************************************************/
1818package org .eclipse .jface .resource ;
1919
20+
2021import java .io .BufferedInputStream ;
2122import java .io .IOException ;
2223import java .io .InputStream ;
2324import java .net .MalformedURLException ;
2425import java .net .URL ;
2526import java .nio .file .Files ;
2627import java .nio .file .Path ;
28+ import java .util .function .Supplier ;
2729
2830import org .eclipse .core .runtime .FileLocator ;
2931import org .eclipse .core .runtime .IAdaptable ;
3840import org .eclipse .swt .graphics .ImageData ;
3941import org .eclipse .swt .graphics .ImageDataProvider ;
4042import org .eclipse .swt .graphics .ImageFileNameProvider ;
43+ import org .eclipse .swt .graphics .ImageLoader ;
44+ import org .eclipse .swt .internal .DPIUtil .ElementAtZoom ;
45+ import org .eclipse .swt .internal .NativeImageLoader ;
46+ import org .eclipse .swt .internal .image .FileFormat ;
4147
4248/**
4349 * An ImageDescriptor that gets its information from a URL. This class is not
@@ -62,16 +68,16 @@ public String getImagePath(int zoom) {
6268 if (zoom == 100 ) {
6369 return getFilePath (tempURL , logIOException );
6470 }
65- URL xUrl = getxURL (tempURL , zoom );
71+ SourceAtZoom < URL > xUrl = getxURL (tempURL , zoom );
6672 if (xUrl != null ) {
67- String xResult = getFilePath (xUrl , logIOException );
73+ String xResult = getFilePath (xUrl . source () , logIOException );
6874 if (xResult != null ) {
6975 return xResult ;
7076 }
7177 }
72- String xpath = FileImageDescriptor .getxPath (url , zoom );
78+ SourceAtZoom < String > xpath = FileImageDescriptor .getxPath (url , zoom );
7379 if (xpath != null ) {
74- URL xPathUrl = getURL (xpath );
80+ URL xPathUrl = getURL (xpath . source () );
7581 if (xPathUrl != null ) {
7682 return getFilePath (xPathUrl , logIOException );
7783 }
@@ -127,7 +133,7 @@ public boolean equals(Object o) {
127133 @ Deprecated
128134 @ Override
129135 public ImageData getImageData () {
130- return getImageData (getURL (url ));
136+ return getImageData (getURL (url ), 100 , 100 );
131137 }
132138
133139 @ Override
@@ -138,32 +144,31 @@ public ImageData getImageData(int zoom) {
138144 private static ImageData getImageData (String url , int zoom ) {
139145 URL tempURL = getURL (url );
140146 if (tempURL != null ) {
141- if (zoom == 100 ) {
142- return getImageData (tempURL );
147+ if (zoom == 100 || canLoadAtZoom (() -> getStream ( tempURL ), zoom ) ) {
148+ return getImageData (tempURL , 100 , zoom );
143149 }
144- URL xUrl = getxURL (tempURL , zoom );
150+ SourceAtZoom < URL > xUrl = getxURL (tempURL , zoom );
145151 if (xUrl != null ) {
146- ImageData xdata = getImageData (xUrl );
152+ ImageData xdata = getImageData (xUrl . source (), xUrl . zoom (), zoom );
147153 if (xdata != null ) {
148154 return xdata ;
149155 }
150156 }
151- String xpath = FileImageDescriptor .getxPath (url , zoom );
157+ SourceAtZoom < String > xpath = FileImageDescriptor .getxPath (url , zoom );
152158 if (xpath != null ) {
153- URL xPathUrl = getURL (xpath );
159+ URL xPathUrl = getURL (xpath . source () );
154160 if (xPathUrl != null ) {
155- return getImageData (xPathUrl );
161+ return getImageData (xPathUrl , xpath . zoom (), zoom );
156162 }
157163 }
158164 }
159165 return null ;
160166 }
161167
162- private static ImageData getImageData (URL url ) {
163- ImageData result = null ;
168+ private static ImageData getImageData (URL url , int fileZoom , int targetZoom ) {
164169 try (InputStream in = getStream (url )) {
165170 if (in != null ) {
166- result = new ImageData (in );
171+ return loadImageFromStream (in , fileZoom , targetZoom );
167172 }
168173 } catch (SWTException e ) {
169174 if (e .code != SWT .ERROR_INVALID_IMAGE ) {
@@ -173,7 +178,42 @@ private static ImageData getImageData(URL url) {
173178 } catch (IOException e ) {
174179 Policy .getLog ().log (Status .error (e .getLocalizedMessage (), e ));
175180 }
176- return result ;
181+ return null ;
182+ }
183+
184+ /**
185+ * Represents an element, such as InputStream, Path or URL, at a specific zoom
186+ * level.
187+ *
188+ * @param <T> type of the element to be presented, e.g., {@link InputStream}
189+ */
190+ record SourceAtZoom <T >(T source , int zoom ) {
191+ public SourceAtZoom {
192+ if (source == null ) {
193+ SWT .error (SWT .ERROR_NULL_ARGUMENT );
194+ }
195+ if (zoom <= 0 ) {
196+ SWT .error (SWT .ERROR_INVALID_ARGUMENT );
197+ }
198+ }
199+ }
200+
201+ @ SuppressWarnings ("restriction" )
202+ static boolean canLoadAtZoom (Supplier <InputStream > streamFactory , int zoom ) {
203+ try (InputStream in = streamFactory .get ()) {
204+ if (in != null ) {
205+ return FileFormat .canLoadAtZoom (new ElementAtZoom <>(in , 100 ), zoom );
206+ }
207+ } catch (IOException e ) {
208+ Policy .getLog ().log (Status .error (e .getLocalizedMessage (), e ));
209+ }
210+ return false ;
211+ }
212+
213+ @ SuppressWarnings ("restriction" )
214+ static ImageData loadImageFromStream (InputStream stream , int fileZoom , int targetZoom ) {
215+ return NativeImageLoader .load (new ElementAtZoom <>(stream , fileZoom ), new ImageLoader (), targetZoom ).get (0 )
216+ .element ();
177217 }
178218
179219 /**
@@ -225,7 +265,7 @@ public String toString() {
225265 return "URLImageDescriptor(" + url + ")" ; //$NON-NLS-1$ //$NON-NLS-2$
226266 }
227267
228- private static URL getxURL (URL url , int zoom ) {
268+ private static SourceAtZoom < URL > getxURL (URL url , int zoom ) {
229269 String path = url .getPath ();
230270 int dot = path .lastIndexOf ('.' );
231271 if (dot != -1 && (zoom == 150 || zoom == 200 )) {
@@ -240,7 +280,7 @@ private static URL getxURL(URL url, int zoom) {
240280 if (url .getQuery () != null ) {
241281 file += '?' + url .getQuery ();
242282 }
243- return new URL (url .getProtocol (), url .getHost (), url .getPort (), file );
283+ return new SourceAtZoom <>( new URL (url .getProtocol (), url .getHost (), url .getPort (), file ), zoom );
244284 } catch (MalformedURLException e ) {
245285 Policy .getLog ().log (Status .error (e .getLocalizedMessage (), e ));
246286 }
0 commit comments