Skip to content

Commit bd7b7dc

Browse files
committed
Extend ImageLoader to able to load images at a given target height and width
Extend ImageLoader to able to load images at a given target height and width in addition to the current behaviour of only being able to load images at a target zoom. This is required to load images in svg format at custom height and width.
1 parent d41bbbe commit bd7b7dc

File tree

10 files changed

+110
-23
lines changed

10 files changed

+110
-23
lines changed

bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ public Image(Device device, InputStream stream) {
692692
try {
693693
byte[] input = stream.readAllBytes();
694694
initWithSupplier(zoom -> ImageDataLoader.canLoadAtZoom(new ByteArrayInputStream(input), FileFormat.DEFAULT_ZOOM, zoom),
695-
zoom -> ImageDataLoader.load(new ByteArrayInputStream(input), FileFormat.DEFAULT_ZOOM, zoom).element());
695+
zoom -> ImageDataLoader.loadByZoom(new ByteArrayInputStream(input), FileFormat.DEFAULT_ZOOM, zoom).element());
696696
init();
697697
} catch (IOException e) {
698698
SWT.error(SWT.ERROR_INVALID_ARGUMENT, e);
@@ -742,7 +742,7 @@ public Image(Device device, String filename) {
742742
initNative(filename);
743743
if (this.handle == null) {
744744
initWithSupplier(zoom -> ImageDataLoader.canLoadAtZoom(filename, FileFormat.DEFAULT_ZOOM, zoom),
745-
zoom -> ImageDataLoader.load(filename, FileFormat.DEFAULT_ZOOM, zoom).element());
745+
zoom -> ImageDataLoader.loadByZoom(filename, FileFormat.DEFAULT_ZOOM, zoom).element());
746746
}
747747
init();
748748
} finally {
@@ -789,7 +789,7 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
789789
if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
790790
try {
791791
initNative(filename);
792-
if (this.handle == null) init(ImageDataLoader.load(filename, 100, 100).element(), 100);
792+
if (this.handle == null) init(ImageDataLoader.loadByZoom(filename, 100, 100).element(), 100);
793793
init();
794794
String filename2x = imageFileNameProvider.getImagePath(200);
795795
if (filename2x != null) {
@@ -799,7 +799,7 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
799799
handle.addRepresentation(rep);
800800
} else if (ImageDataLoader.canLoadAtZoom(filename, 100, 200)) {
801801
// Try to natively scale up the image (e.g. possible if it's an SVG)
802-
ImageData imageData2x = ImageDataLoader.load(filename, 100, 200).element();
802+
ImageData imageData2x = ImageDataLoader.loadByZoom(filename, 100, 200).element();
803803
alphaInfo_200 = new AlphaInfo();
804804
NSBitmapImageRep rep = createRepresentation (imageData2x, alphaInfo_200);
805805
handle.addRepresentation(rep);

bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/internal/NativeImageLoader.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ public static List<ElementAtZoom<ImageData>> load(ElementAtZoom<InputStream> str
2626
return FileFormat.load(streamAtZoom, imageLoader, targetZoom);
2727
}
2828

29+
public static ImageData load(InputStream streamAtZoom, ImageLoader imageLoader, int targetWidth, int targetHeight) {
30+
return FileFormat.load(streamAtZoom, imageLoader, targetWidth, targetHeight);
31+
}
32+
2933
public static void save(OutputStream stream, int format, ImageLoader imageLoader) {
3034
FileFormat.save(stream, format, imageLoader);
3135
}

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageDataLoader.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,32 @@ public static boolean canLoadAtZoom(InputStream stream, int fileZoom, int target
4141
return ImageLoader.canLoadAtZoom(stream, fileZoom, targetZoom);
4242
}
4343

44-
public static ElementAtZoom<ImageData> load(InputStream stream, int fileZoom, int targetZoom) {
45-
List<ElementAtZoom<ImageData>> data = new ImageLoader().load(stream, fileZoom, targetZoom);
46-
if (data.isEmpty()) SWT.error(SWT.ERROR_INVALID_IMAGE);
47-
return data.get(0);
48-
}
49-
5044
public static boolean canLoadAtZoom(String filename, int fileZoom, int targetZoom) {
5145
return ImageLoader.canLoadAtZoom(filename, fileZoom, targetZoom);
5246
}
5347

54-
public static ElementAtZoom<ImageData> load(String filename, int fileZoom, int targetZoom) {
55-
List<ElementAtZoom<ImageData>> data = new ImageLoader().load(filename, fileZoom, targetZoom);
48+
public static ElementAtZoom<ImageData> loadByZoom(InputStream stream, int fileZoom, int targetZoom) {
49+
List<ElementAtZoom<ImageData>> data = new ImageLoader().loadByZoom(stream, fileZoom, targetZoom);
50+
if (data.isEmpty()) SWT.error(SWT.ERROR_INVALID_IMAGE);
51+
return data.get(0);
52+
}
53+
54+
public static ElementAtZoom<ImageData> loadByZoom(String filename, int fileZoom, int targetZoom) {
55+
List<ElementAtZoom<ImageData>> data = new ImageLoader().loadByZoom(filename, fileZoom, targetZoom);
5656
if (data.isEmpty()) SWT.error(SWT.ERROR_INVALID_IMAGE);
5757
return data.get(0);
5858
}
5959

60+
public static ImageData loadByTargetSize(InputStream stream, int targetWidth, int targetHeight) {
61+
ImageData data = new ImageLoader().loadByTargetSize(stream, targetWidth, targetHeight);
62+
if (data == null) SWT.error(SWT.ERROR_INVALID_IMAGE);
63+
return data;
64+
}
65+
66+
public static ImageData loadByTargetSize(String filename, int targetWidth, int targetHeight) {
67+
ImageData data = new ImageLoader().loadByTargetSize(filename, targetWidth, targetHeight);
68+
if (data == null) SWT.error(SWT.ERROR_INVALID_IMAGE);
69+
return data;
70+
}
71+
6072
}

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageLoader.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,18 +151,26 @@ void reset() {
151151
* </ul>
152152
*/
153153
public ImageData[] load(InputStream stream) {
154-
load(stream, FileFormat.DEFAULT_ZOOM, FileFormat.DEFAULT_ZOOM);
154+
loadByZoom(stream, FileFormat.DEFAULT_ZOOM, FileFormat.DEFAULT_ZOOM);
155155
return data;
156156
}
157157

158-
List<ElementAtZoom<ImageData>> load(InputStream stream, int fileZoom, int targetZoom) {
158+
List<ElementAtZoom<ImageData>> loadByZoom(InputStream stream, int fileZoom, int targetZoom) {
159159
if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
160160
reset();
161161
List<ElementAtZoom<ImageData>> images = NativeImageLoader.load(new ElementAtZoom<>(stream, fileZoom), this, targetZoom);
162162
data = images.stream().map(ElementAtZoom::element).toArray(ImageData[]::new);
163163
return images;
164164
}
165165

166+
ImageData loadByTargetSize(InputStream stream, int targetWidth, int targetHeight) {
167+
if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
168+
reset();
169+
ImageData image = NativeImageLoader.load(stream, this, targetWidth, targetHeight);
170+
data = new ImageData[] {image};
171+
return image;
172+
}
173+
166174
static boolean canLoadAtZoom(InputStream stream, int fileZoom, int targetZoom) {
167175
if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
168176
return FileFormat.canLoadAtZoom(new ElementAtZoom<>(stream, fileZoom), targetZoom);
@@ -187,14 +195,24 @@ static boolean canLoadAtZoom(InputStream stream, int fileZoom, int targetZoom) {
187195
* </ul>
188196
*/
189197
public ImageData[] load(String filename) {
190-
load(filename, FileFormat.DEFAULT_ZOOM, FileFormat.DEFAULT_ZOOM);
198+
loadByZoom(filename, FileFormat.DEFAULT_ZOOM, FileFormat.DEFAULT_ZOOM);
191199
return data;
192200
}
193201

194-
List<ElementAtZoom<ImageData>> load(String filename, int fileZoom, int targetZoom) {
202+
List<ElementAtZoom<ImageData>> loadByZoom(String filename, int fileZoom, int targetZoom) {
203+
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
204+
try (InputStream stream = new FileInputStream(filename)) {
205+
return loadByZoom(stream, fileZoom, targetZoom);
206+
} catch (IOException e) {
207+
SWT.error(SWT.ERROR_IO, e);
208+
}
209+
return null;
210+
}
211+
212+
ImageData loadByTargetSize(String filename, int targetWidth, int targetHeight) {
195213
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
196214
try (InputStream stream = new FileInputStream(filename)) {
197-
return load(stream, fileZoom, targetZoom);
215+
return loadByTargetSize(stream, targetWidth, targetHeight);
198216
} catch (IOException e) {
199217
SWT.error(SWT.ERROR_IO, e);
200218
}

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/FileFormat.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ static abstract class StaticImageFileFormat extends FileFormat {
8585
List<ElementAtZoom<ImageData>> loadFromByteStream(int fileZoom, int targetZoom) {
8686
return Arrays.stream(loadFromByteStream()).map(d -> new ElementAtZoom<>(d, fileZoom)).toList();
8787
}
88+
89+
@Override
90+
ImageData loadFromByteStreamByTargetSize(int targetWidth, int targetHeight) {
91+
return loadFromByteStream()[0];
92+
}
8893
}
8994

9095
LEDataInputStream inputStream;
@@ -104,6 +109,8 @@ List<ElementAtZoom<ImageData>> loadFromByteStream(int fileZoom, int targetZoom)
104109
*/
105110
abstract List<ElementAtZoom<ImageData>> loadFromByteStream(int fileZoom, int targetZoom);
106111

112+
abstract ImageData loadFromByteStreamByTargetSize(int targetWidth, int targetHeight);
113+
107114
/**
108115
* Read the specified input stream, and return the
109116
* device independent image array represented by the stream.
@@ -122,6 +129,20 @@ public List<ElementAtZoom<ImageData>> loadFromStream(LEDataInputStream stream, i
122129
}
123130
}
124131

132+
public ImageData loadFromStreamByTargetSize(LEDataInputStream stream, int targetWidth, int targetHeight) {
133+
try {
134+
inputStream = stream;
135+
return loadFromByteStreamByTargetSize(targetWidth, targetHeight);
136+
} catch (Exception e) {
137+
if (e instanceof IOException) {
138+
SWT.error(SWT.ERROR_IO, e);
139+
} else {
140+
SWT.error(SWT.ERROR_INVALID_IMAGE, e);
141+
}
142+
return null;
143+
}
144+
}
145+
125146
/**
126147
* Read the specified input stream using the specified loader, and
127148
* return the device independent image array represented by the stream.
@@ -136,6 +157,16 @@ public static List<ElementAtZoom<ImageData>> load(ElementAtZoom<InputStream> is,
136157
return fileFormat.loadFromStream(stream, is.zoom(), targetZoom);
137158
}
138159

160+
public static ImageData load(InputStream is, ImageLoader loader, int targetWidth, int targetHeight) {
161+
LEDataInputStream stream = new LEDataInputStream(is);
162+
FileFormat fileFormat = determineFileFormat(stream).orElseGet(() -> {
163+
SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT);
164+
return null;
165+
});
166+
fileFormat.loader = loader;
167+
return fileFormat.loadFromStreamByTargetSize(stream, targetWidth, targetHeight);
168+
}
169+
139170
public static boolean canLoadAtZoom(ElementAtZoom<InputStream> is, int targetZoom) {
140171
return is.zoom() == targetZoom || isDynamicallySizableFormat(is.element());
141172
}

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/image/SVGFileFormat.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,20 @@ List<ElementAtZoom<ImageData>> loadFromByteStream(int fileZoom, int targetZoom)
6060
}
6161
}
6262

63+
@Override
64+
ImageData loadFromByteStreamByTargetSize(int targetWidth, int targetHeight) {
65+
if (RASTERIZER == null) {
66+
SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT, null, " [No SVG rasterizer found]");
67+
}
68+
try {
69+
ImageData rasterizedImageData = RASTERIZER.rasterizeSVG(inputStream, targetWidth, targetHeight);
70+
return rasterizedImageData;
71+
} catch (IOException e) {
72+
SWT.error(SWT.ERROR_INVALID_IMAGE, e);
73+
return null;
74+
}
75+
}
76+
6377
@Override
6478
void unloadIntoByteStream(ImageLoader loader) {
6579
throw new UnsupportedOperationException();

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ public Image(Device device, ImageData source, ImageData mask) {
552552
public Image(Device device, InputStream stream) {
553553
super(device);
554554
currentDeviceZoom = DPIUtil.getDeviceZoom();
555-
ElementAtZoom<ImageData> image = ImageDataLoader.load(stream, FileFormat.DEFAULT_ZOOM, currentDeviceZoom);
555+
ElementAtZoom<ImageData> image = ImageDataLoader.loadByZoom(stream, FileFormat.DEFAULT_ZOOM, currentDeviceZoom);
556556
ImageData data = DPIUtil.scaleImageData(device, image, currentDeviceZoom);
557557
init(data);
558558
init();
@@ -594,7 +594,7 @@ public Image(Device device, String filename) {
594594
super(device);
595595
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
596596
currentDeviceZoom = DPIUtil.getDeviceZoom();
597-
ElementAtZoom<ImageData> image = ImageDataLoader.load(filename, FileFormat.DEFAULT_ZOOM, currentDeviceZoom);
597+
ElementAtZoom<ImageData> image = ImageDataLoader.loadByZoom(filename, FileFormat.DEFAULT_ZOOM, currentDeviceZoom);
598598
ImageData data = DPIUtil.scaleImageData(device, image, currentDeviceZoom);
599599
init(data);
600600
init();
@@ -785,7 +785,7 @@ private void initFromFileNameProvider(int zoom) {
785785
initNative(fileForZoom.element());
786786
}
787787
if (this.surface == 0) {
788-
ElementAtZoom<ImageData> imageDataAtZoom = ImageDataLoader.load(fileForZoom.element(), fileForZoom.zoom(), zoom);
788+
ElementAtZoom<ImageData> imageDataAtZoom = ImageDataLoader.loadByZoom(fileForZoom.element(), fileForZoom.zoom(), zoom);
789789
ImageData imageData = imageDataAtZoom.element();
790790
if (imageDataAtZoom.zoom() != zoom) {
791791
imageData = DPIUtil.scaleImageData(device, imageDataAtZoom, zoom);

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/NativeImageLoader.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ public static List<ElementAtZoom<ImageData>> load(ElementAtZoom<InputStream> str
142142
return Arrays.stream(imgDataArray).map(data -> new ElementAtZoom<>(data, streamAtZoom.zoom())).toList();
143143
}
144144

145+
public static ImageData load(InputStream streamAtZoom, ImageLoader imageLoader, int targetWidth, int targetHeight) {
146+
return FileFormat.load(streamAtZoom, imageLoader, targetWidth, targetHeight);
147+
}
148+
145149
/**
146150
* Return true if the image is an interlaced PNG file. This is used to check
147151
* whether ImageLoaderEvent should be fired when loading images.

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2119,7 +2119,7 @@ private ImageDataLoaderStreamProviderWrapper(byte[] inputStreamData) {
21192119

21202120
@Override
21212121
protected ElementAtZoom<ImageData> loadImageData(int zoom) {
2122-
return ImageDataLoader.load(new ByteArrayInputStream(inputStreamData), FileFormat.DEFAULT_ZOOM, zoom);
2122+
return ImageDataLoader.loadByZoom(new ByteArrayInputStream(inputStreamData), FileFormat.DEFAULT_ZOOM, zoom);
21232123
}
21242124

21252125
@Override
@@ -2341,7 +2341,7 @@ protected ElementAtZoom<ImageData> loadImageData(int zoom) {
23412341

23422342
// Load at appropriate zoom via loader
23432343
if (fileForZoom.zoom() != zoom && ImageDataLoader.canLoadAtZoom(fileForZoom.element(), fileForZoom.zoom(), zoom)) {
2344-
ElementAtZoom<ImageData> imageDataAtZoom = ImageDataLoader.load(fileForZoom.element(), fileForZoom.zoom(), zoom);
2344+
ElementAtZoom<ImageData> imageDataAtZoom = ImageDataLoader.loadByZoom(fileForZoom.element(), fileForZoom.zoom(), zoom);
23452345
return new ElementAtZoom<>(imageDataAtZoom.element(), zoom);
23462346
}
23472347

@@ -2354,7 +2354,7 @@ protected ElementAtZoom<ImageData> loadImageData(int zoom) {
23542354
}
23552355
ElementAtZoom<ImageData> imageDataAtZoom;
23562356
if (nativeInitializedImage == null) {
2357-
imageDataAtZoom = ImageDataLoader.load(fileForZoom.element(), fileForZoom.zoom(), zoom);
2357+
imageDataAtZoom = ImageDataLoader.loadByZoom(fileForZoom.element(), fileForZoom.zoom(), zoom);
23582358
} else {
23592359
imageDataAtZoom = new ElementAtZoom<>(nativeInitializedImage.getImageData(), fileForZoom.zoom());
23602360
nativeInitializedImage.destroy();

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/NativeImageLoader.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ public static List<ElementAtZoom<ImageData>> load(ElementAtZoom<InputStream> str
2626
return FileFormat.load(streamAtZoom, imageLoader, targetZoom);
2727
}
2828

29+
public static ImageData load(InputStream streamAtZoom, ImageLoader imageLoader, int targetWidth, int targetHeight) {
30+
return FileFormat.load(streamAtZoom, imageLoader, targetWidth, targetHeight);
31+
}
32+
2933
public static void save(OutputStream stream, int format, ImageLoader imageLoader) {
3034
FileFormat.save(stream, format, imageLoader);
3135
}

0 commit comments

Comments
 (0)