diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java index 0dc7f5e36d5..62bee06ab07 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java @@ -692,7 +692,7 @@ public Image(Device device, InputStream stream) { try { byte[] input = stream.readAllBytes(); initWithSupplier(zoom -> ImageDataLoader.canLoadAtZoom(new ByteArrayInputStream(input), FileFormat.DEFAULT_ZOOM, zoom), - zoom -> ImageDataLoader.load(new ByteArrayInputStream(input), FileFormat.DEFAULT_ZOOM, zoom).element()); + zoom -> ImageDataLoader.loadByZoom(new ByteArrayInputStream(input), FileFormat.DEFAULT_ZOOM, zoom).element()); init(); } catch (IOException e) { SWT.error(SWT.ERROR_INVALID_ARGUMENT, e); @@ -742,7 +742,7 @@ public Image(Device device, String filename) { initNative(filename); if (this.handle == null) { initWithSupplier(zoom -> ImageDataLoader.canLoadAtZoom(filename, FileFormat.DEFAULT_ZOOM, zoom), - zoom -> ImageDataLoader.load(filename, FileFormat.DEFAULT_ZOOM, zoom).element()); + zoom -> ImageDataLoader.loadByZoom(filename, FileFormat.DEFAULT_ZOOM, zoom).element()); } init(); } finally { @@ -789,7 +789,7 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) { if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); try { initNative(filename); - if (this.handle == null) init(ImageDataLoader.load(filename, 100, 100).element(), 100); + if (this.handle == null) init(ImageDataLoader.loadByZoom(filename, 100, 100).element(), 100); init(); String filename2x = imageFileNameProvider.getImagePath(200); if (filename2x != null) { @@ -799,7 +799,7 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) { handle.addRepresentation(rep); } else if (ImageDataLoader.canLoadAtZoom(filename, 100, 200)) { // Try to natively scale up the image (e.g. possible if it's an SVG) - ImageData imageData2x = ImageDataLoader.load(filename, 100, 200).element(); + ImageData imageData2x = ImageDataLoader.loadByZoom(filename, 100, 200).element(); alphaInfo_200 = new AlphaInfo(); NSBitmapImageRep rep = createRepresentation (imageData2x, alphaInfo_200); handle.addRepresentation(rep); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/internal/NativeImageLoader.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/internal/NativeImageLoader.java index 09b39591368..8752a513d5f 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/internal/NativeImageLoader.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/internal/NativeImageLoader.java @@ -26,6 +26,10 @@ public static List> load(ElementAtZoom str return FileFormat.load(streamAtZoom, imageLoader, targetZoom); } + public static ImageData load(InputStream streamAtZoom, ImageLoader imageLoader, int width, int height) { + return FileFormat.load(streamAtZoom, imageLoader, width, height); + } + public static void save(OutputStream stream, int format, ImageLoader imageLoader) { FileFormat.save(stream, format, imageLoader); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageDataLoader.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageDataLoader.java index 29f517b45c0..7ee6077dba3 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageDataLoader.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageDataLoader.java @@ -41,20 +41,32 @@ public static boolean canLoadAtZoom(InputStream stream, int fileZoom, int target return ImageLoader.canLoadAtZoom(stream, fileZoom, targetZoom); } - public static ElementAtZoom load(InputStream stream, int fileZoom, int targetZoom) { - List> data = new ImageLoader().load(stream, fileZoom, targetZoom); - if (data.isEmpty()) SWT.error(SWT.ERROR_INVALID_IMAGE); - return data.get(0); - } - public static boolean canLoadAtZoom(String filename, int fileZoom, int targetZoom) { return ImageLoader.canLoadAtZoom(filename, fileZoom, targetZoom); } - public static ElementAtZoom load(String filename, int fileZoom, int targetZoom) { - List> data = new ImageLoader().load(filename, fileZoom, targetZoom); + public static ElementAtZoom loadByZoom(InputStream stream, int fileZoom, int targetZoom) { + List> data = new ImageLoader().loadByZoom(stream, fileZoom, targetZoom); + if (data.isEmpty()) SWT.error(SWT.ERROR_INVALID_IMAGE); + return data.get(0); + } + + public static ElementAtZoom loadByZoom(String filename, int fileZoom, int targetZoom) { + List> data = new ImageLoader().loadByZoom(filename, fileZoom, targetZoom); if (data.isEmpty()) SWT.error(SWT.ERROR_INVALID_IMAGE); return data.get(0); } + public static ImageData loadBySize(InputStream stream, int width, int height) { + ImageData data = new ImageLoader().loadBySize(stream, width, height); + if (data == null) SWT.error(SWT.ERROR_INVALID_IMAGE); + return data; + } + + public static ImageData loadBySize(String filename, int width, int height) { + ImageData data = new ImageLoader().loadBySize(filename, width, height); + if (data == null) SWT.error(SWT.ERROR_INVALID_IMAGE); + return data; + } + } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoader.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoader.java index 9973b8f06e3..989627e0956 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoader.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoader.java @@ -151,11 +151,11 @@ void reset() { * */ public ImageData[] load(InputStream stream) { - load(stream, FileFormat.DEFAULT_ZOOM, FileFormat.DEFAULT_ZOOM); + loadByZoom(stream, FileFormat.DEFAULT_ZOOM, FileFormat.DEFAULT_ZOOM); return data; } -List> load(InputStream stream, int fileZoom, int targetZoom) { +List> loadByZoom(InputStream stream, int fileZoom, int targetZoom) { if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); reset(); List> images = NativeImageLoader.load(new ElementAtZoom<>(stream, fileZoom), this, targetZoom); @@ -163,6 +163,14 @@ List> load(InputStream stream, int fileZoom, int target return images; } +ImageData loadBySize(InputStream stream, int width, int height) { + if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + reset(); + ImageData image = NativeImageLoader.load(stream, this, width, height); + data = new ImageData[] {image}; + return image; +} + static boolean canLoadAtZoom(InputStream stream, int fileZoom, int targetZoom) { if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); return FileFormat.canLoadAtZoom(new ElementAtZoom<>(stream, fileZoom), targetZoom); @@ -187,14 +195,24 @@ static boolean canLoadAtZoom(InputStream stream, int fileZoom, int targetZoom) { * */ public ImageData[] load(String filename) { - load(filename, FileFormat.DEFAULT_ZOOM, FileFormat.DEFAULT_ZOOM); + loadByZoom(filename, FileFormat.DEFAULT_ZOOM, FileFormat.DEFAULT_ZOOM); return data; } -List> load(String filename, int fileZoom, int targetZoom) { +List> loadByZoom(String filename, int fileZoom, int targetZoom) { + if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); + try (InputStream stream = new FileInputStream(filename)) { + return loadByZoom(stream, fileZoom, targetZoom); + } catch (IOException e) { + SWT.error(SWT.ERROR_IO, e); + } + return null; +} + +ImageData loadBySize(String filename, int width, int height) { if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); try (InputStream stream = new FileInputStream(filename)) { - return load(stream, fileZoom, targetZoom); + return loadBySize(stream, width, height); } catch (IOException e) { SWT.error(SWT.ERROR_IO, e); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/FileFormat.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/FileFormat.java index 8232d71023d..dfd5e265199 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/FileFormat.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/FileFormat.java @@ -85,6 +85,11 @@ static abstract class StaticImageFileFormat extends FileFormat { List> loadFromByteStream(int fileZoom, int targetZoom) { return Arrays.stream(loadFromByteStream()).map(d -> new ElementAtZoom<>(d, fileZoom)).toList(); } + + @Override + ImageData loadFromByteStreamBySize(int width, int height) { + return loadFromByteStream()[0]; + } } LEDataInputStream inputStream; @@ -104,6 +109,8 @@ List> loadFromByteStream(int fileZoom, int targetZoom) */ abstract List> loadFromByteStream(int fileZoom, int targetZoom); + abstract ImageData loadFromByteStreamBySize(int width, int height); + /** * Read the specified input stream, and return the * device independent image array represented by the stream. @@ -122,6 +129,20 @@ public List> loadFromStream(LEDataInputStream stream, i } } +public ImageData loadFromStreamBySize(LEDataInputStream stream, int width, int height) { + try { + inputStream = stream; + return loadFromByteStreamBySize(width, height); + } catch (Exception e) { + if (e instanceof IOException) { + SWT.error(SWT.ERROR_IO, e); + } else { + SWT.error(SWT.ERROR_INVALID_IMAGE, e); + } + return null; + } +} + /** * Read the specified input stream using the specified loader, and * return the device independent image array represented by the stream. @@ -136,6 +157,16 @@ public static List> load(ElementAtZoom is, return fileFormat.loadFromStream(stream, is.zoom(), targetZoom); } +public static ImageData load(InputStream is, ImageLoader loader, int width, int height) { + LEDataInputStream stream = new LEDataInputStream(is); + FileFormat fileFormat = determineFileFormat(stream).orElseGet(() -> { + SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT); + return null; + }); + fileFormat.loader = loader; + return fileFormat.loadFromStreamBySize(stream, width, height); +} + public static boolean canLoadAtZoom(ElementAtZoom is, int targetZoom) { return is.zoom() == targetZoom || isDynamicallySizableFormat(is.element()); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/SVGFileFormat.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/SVGFileFormat.java index 69394251d6c..b985d5ceadb 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/SVGFileFormat.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/SVGFileFormat.java @@ -55,6 +55,18 @@ List> loadFromByteStream(int fileZoom, int targetZoom) return List.of(new ElementAtZoom<>(rasterizedImageData, targetZoom)); } + @Override + ImageData loadFromByteStreamBySize(int width, int height) { + if (RASTERIZER == null) { + SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT, null, " [No SVG rasterizer found]"); + } + if (width <= 0 || height <= 0) { + SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, " [Cannot rasterize SVG for width or height <= 0]"); + } + ImageData rasterizedImageData = RASTERIZER.rasterizeSVG(inputStream, width, height); + return rasterizedImageData; + } + @Override void unloadIntoByteStream(ImageLoader loader) { throw new UnsupportedOperationException(); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java index f77c83f79e9..131807e57cf 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java @@ -552,7 +552,7 @@ public Image(Device device, ImageData source, ImageData mask) { public Image(Device device, InputStream stream) { super(device); currentDeviceZoom = DPIUtil.getDeviceZoom(); - ElementAtZoom image = ImageDataLoader.load(stream, FileFormat.DEFAULT_ZOOM, currentDeviceZoom); + ElementAtZoom image = ImageDataLoader.loadByZoom(stream, FileFormat.DEFAULT_ZOOM, currentDeviceZoom); ImageData data = DPIUtil.scaleImageData(device, image, currentDeviceZoom); init(data); init(); @@ -594,7 +594,7 @@ public Image(Device device, String filename) { super(device); if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); currentDeviceZoom = DPIUtil.getDeviceZoom(); - ElementAtZoom image = ImageDataLoader.load(filename, FileFormat.DEFAULT_ZOOM, currentDeviceZoom); + ElementAtZoom image = ImageDataLoader.loadByZoom(filename, FileFormat.DEFAULT_ZOOM, currentDeviceZoom); ImageData data = DPIUtil.scaleImageData(device, image, currentDeviceZoom); init(data); init(); @@ -785,7 +785,7 @@ private void initFromFileNameProvider(int zoom) { initNative(fileForZoom.element()); } if (this.surface == 0) { - ElementAtZoom imageDataAtZoom = ImageDataLoader.load(fileForZoom.element(), fileForZoom.zoom(), zoom); + ElementAtZoom imageDataAtZoom = ImageDataLoader.loadByZoom(fileForZoom.element(), fileForZoom.zoom(), zoom); ImageData imageData = imageDataAtZoom.element(); if (imageDataAtZoom.zoom() != zoom) { imageData = DPIUtil.scaleImageData(device, imageDataAtZoom, zoom); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/NativeImageLoader.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/NativeImageLoader.java index 838fd72cd36..0aa8a25210a 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/NativeImageLoader.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/NativeImageLoader.java @@ -142,6 +142,10 @@ public static List> load(ElementAtZoom str return Arrays.stream(imgDataArray).map(data -> new ElementAtZoom<>(data, streamAtZoom.zoom())).toList(); } + public static ImageData load(InputStream streamAtZoom, ImageLoader imageLoader, int width, int height) { + return FileFormat.load(streamAtZoom, imageLoader, width, height); + } + /** * Return true if the image is an interlaced PNG file. This is used to check * whether ImageLoaderEvent should be fired when loading images. diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java index 2e665685127..200dd55911d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java @@ -2127,7 +2127,7 @@ private ImageDataLoaderStreamProviderWrapper(byte[] inputStreamData) { @Override protected ElementAtZoom loadImageData(int zoom) { - return ImageDataLoader.load(new ByteArrayInputStream(inputStreamData), FileFormat.DEFAULT_ZOOM, zoom); + return ImageDataLoader.loadByZoom(new ByteArrayInputStream(inputStreamData), FileFormat.DEFAULT_ZOOM, zoom); } @Override @@ -2349,7 +2349,7 @@ protected ElementAtZoom loadImageData(int zoom) { // Load at appropriate zoom via loader if (fileForZoom.zoom() != zoom && ImageDataLoader.canLoadAtZoom(fileForZoom.element(), fileForZoom.zoom(), zoom)) { - ElementAtZoom imageDataAtZoom = ImageDataLoader.load(fileForZoom.element(), fileForZoom.zoom(), zoom); + ElementAtZoom imageDataAtZoom = ImageDataLoader.loadByZoom(fileForZoom.element(), fileForZoom.zoom(), zoom); return new ElementAtZoom<>(imageDataAtZoom.element(), zoom); } @@ -2362,7 +2362,7 @@ protected ElementAtZoom loadImageData(int zoom) { } ElementAtZoom imageDataAtZoom; if (nativeInitializedImage == null) { - imageDataAtZoom = ImageDataLoader.load(fileForZoom.element(), fileForZoom.zoom(), zoom); + imageDataAtZoom = ImageDataLoader.loadByZoom(fileForZoom.element(), fileForZoom.zoom(), zoom); } else { imageDataAtZoom = new ElementAtZoom<>(nativeInitializedImage.getImageData(), fileForZoom.zoom()); nativeInitializedImage.destroy(); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/NativeImageLoader.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/NativeImageLoader.java index 09b39591368..8752a513d5f 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/NativeImageLoader.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/NativeImageLoader.java @@ -26,6 +26,10 @@ public static List> load(ElementAtZoom str return FileFormat.load(streamAtZoom, imageLoader, targetZoom); } + public static ImageData load(InputStream streamAtZoom, ImageLoader imageLoader, int width, int height) { + return FileFormat.load(streamAtZoom, imageLoader, width, height); + } + public static void save(OutputStream stream, int format, ImageLoader imageLoader) { FileFormat.save(stream, format, imageLoader); }