@@ -366,9 +366,7 @@ public Image(Device device, ImageData data) {
366
366
super (device );
367
367
if (data == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
368
368
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
369
- int deviceZoom = getZoom ();
370
- data = DPIUtil .scaleImageData (device , new ElementAtZoom <>(data , 100 ), deviceZoom );
371
- init (data , deviceZoom );
369
+ this .imageProvider = new PlainImageDataProviderWrapper (data );
372
370
init ();
373
371
this .device .registerResourceWithZoomSupport (this );
374
372
}
@@ -411,10 +409,7 @@ public Image(Device device, ImageData source, ImageData mask) {
411
409
SWT .error (SWT .ERROR_INVALID_ARGUMENT );
412
410
}
413
411
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
414
- source = DPIUtil .autoScaleUp (device , source );
415
- mask = DPIUtil .autoScaleUp (device , mask );
416
- mask = ImageData .convertMask (mask );
417
- initIconHandle (this .device , source , mask , getZoom ());
412
+ this .imageProvider = new MaskedImageDataProviderWrapper (source , mask );
418
413
init ();
419
414
this .device .registerResourceWithZoomSupport (this );
420
415
}
@@ -474,10 +469,12 @@ public Image(Device device, ImageData source, ImageData mask) {
474
469
*/
475
470
public Image (Device device , InputStream stream ) {
476
471
super (device );
472
+ if (stream == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
477
473
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
478
- int deviceZoom = getZoom ();
479
- ImageData data = DPIUtil .scaleImageData (device , ImageDataLoader .load (stream , FileFormat .DEFAULT_ZOOM , deviceZoom ), deviceZoom );
480
- init (data , deviceZoom );
474
+ this .imageProvider = new ImageDataLoaderStreamProviderWrapper (stream );
475
+ if (this .imageProvider .getImageData (100 ) == null ) {
476
+ SWT .error (SWT .ERROR_INVALID_ARGUMENT , null , ": InputStream returns null ImageData at 100% zoom." );
477
+ }
481
478
init ();
482
479
this .device .registerResourceWithZoomSupport (this );
483
480
}
@@ -518,9 +515,10 @@ public Image (Device device, String filename) {
518
515
super (device );
519
516
if (filename == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
520
517
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
521
- int deviceZoom = getZoom ();
522
- ImageData data = DPIUtil .scaleImageData (device , ImageDataLoader .load (filename , FileFormat .DEFAULT_ZOOM , deviceZoom ), deviceZoom );
523
- init (data , deviceZoom );
518
+ this .imageProvider = new ImageDataLoaderFileProviderWrapper (filename );
519
+ if (this .imageProvider .getImageData (100 ) == null ) {
520
+ SWT .error (SWT .ERROR_INVALID_ARGUMENT , null , ": Input filename returns null ImageData at 100% zoom." );
521
+ }
524
522
init ();
525
523
this .device .registerResourceWithZoomSupport (this );
526
524
}
@@ -626,6 +624,14 @@ public Image(Device device, ImageGcDrawer imageGcDrawer, int width, int height)
626
624
init ();
627
625
}
628
626
627
+ @ Override
628
+ void init () {
629
+ super .init ();
630
+ if (this .imageProvider != null ) {
631
+ this .imageProvider .initImage ();
632
+ }
633
+ }
634
+
629
635
private ImageData adaptImageDataIfDisabledOrGray (ImageData data ) {
630
636
ImageData returnImageData = null ;
631
637
switch (this .styleFlag ) {
@@ -1885,10 +1891,168 @@ private abstract class AbstractImageProviderWrapper {
1885
1891
abstract AbstractImageProviderWrapper createCopy (Image image );
1886
1892
abstract boolean isDisposed ();
1887
1893
1894
+ protected void initImage () {
1895
+ }
1896
+
1888
1897
protected void destroy () {
1889
1898
}
1890
1899
}
1891
1900
1901
+ private abstract class ImageFromImageDataProviderWrapper extends AbstractImageProviderWrapper {
1902
+ private boolean isDestroyed ;
1903
+
1904
+ protected abstract ElementAtZoom <ImageData > loadImageData (int zoom );
1905
+
1906
+ @ Override
1907
+ protected void initImage () {
1908
+ ImageData imageDataAt100 = getImageData (100 );
1909
+ init (imageDataAt100 , 100 );
1910
+ destroyHandleForZoom (100 );
1911
+ }
1912
+
1913
+ @ Override
1914
+ ImageData getImageData (int zoom ) {
1915
+ if (zoomLevelToImageHandle .containsKey (zoom )) {
1916
+ return zoomLevelToImageHandle .get (zoom ).getImageData ();
1917
+ }
1918
+ ElementAtZoom <ImageData > loadedImageData = loadImageData (zoom );
1919
+ return DPIUtil .scaleImageData (device , loadedImageData , zoom );
1920
+ }
1921
+
1922
+ @ Override
1923
+ ImageHandle getImageMetadata (int zoom ) {
1924
+ if (zoomLevelToImageHandle .containsKey (zoom )) {
1925
+ return zoomLevelToImageHandle .get (zoom );
1926
+ } else {
1927
+ ImageData scaledImageData = getImageData (zoom );
1928
+ ImageHandle imageHandle = init (scaledImageData , zoom );
1929
+ return imageHandle ;
1930
+ }
1931
+ }
1932
+
1933
+ @ Override
1934
+ protected void destroy () {
1935
+ this .isDestroyed = true ;
1936
+ }
1937
+
1938
+ @ Override
1939
+ boolean isDisposed () {
1940
+ return isDestroyed ;
1941
+ }
1942
+ }
1943
+
1944
+
1945
+ private class MaskedImageDataProviderWrapper extends ImageFromImageDataProviderWrapper {
1946
+ private final ImageData srcAt100 ;
1947
+ private final ImageData maskAt100 ;
1948
+
1949
+ MaskedImageDataProviderWrapper (ImageData srcAt100 , ImageData maskAt100 ) {
1950
+ this .srcAt100 = (ImageData ) srcAt100 .clone ();
1951
+ this .maskAt100 = (ImageData ) maskAt100 .clone ();
1952
+ }
1953
+
1954
+ @ Override
1955
+ protected Rectangle getBounds (int zoom ) {
1956
+ Rectangle rectangle = new Rectangle (0 , 0 , srcAt100 .width , srcAt100 .height );
1957
+ return DPIUtil .scaleUp (rectangle , zoom );
1958
+ }
1959
+
1960
+ @ Override
1961
+ protected ElementAtZoom <ImageData > loadImageData (int zoom ) {
1962
+ ImageData scaledSource = DPIUtil .scaleImageData (device , srcAt100 , zoom , 100 );
1963
+ ImageData mask = ImageData .convertMask (maskAt100 );
1964
+ ImageData scaledMask = DPIUtil .scaleImageData (device , mask , zoom , 100 );
1965
+ ImageData mergedData = applyMask (scaledSource , scaledMask );
1966
+ return new ElementAtZoom <>(mergedData , zoom );
1967
+ }
1968
+
1969
+ @ Override
1970
+ AbstractImageProviderWrapper createCopy (Image image ) {
1971
+ return image .new MaskedImageDataProviderWrapper (this .srcAt100 , this .maskAt100 );
1972
+ }
1973
+ }
1974
+
1975
+
1976
+ private class PlainImageDataProviderWrapper extends ImageFromImageDataProviderWrapper {
1977
+ private ImageData imageDataAt100 ;
1978
+
1979
+ PlainImageDataProviderWrapper (ImageData imageData ) {
1980
+ this .imageDataAt100 = (ImageData ) imageData .clone ();
1981
+ }
1982
+
1983
+ @ Override
1984
+ protected Rectangle getBounds (int zoom ) {
1985
+ Rectangle rectangle = new Rectangle (0 , 0 , imageDataAt100 .width , imageDataAt100 .height );
1986
+ return DPIUtil .scaleUp (rectangle , zoom );
1987
+ }
1988
+
1989
+ @ Override
1990
+ protected ElementAtZoom <ImageData > loadImageData (int zoom ) {
1991
+ return new ElementAtZoom <>(imageDataAt100 , 100 );
1992
+ }
1993
+
1994
+ @ Override
1995
+ AbstractImageProviderWrapper createCopy (Image image ) {
1996
+ return image .new PlainImageDataProviderWrapper (this .imageDataAt100 );
1997
+ }
1998
+ }
1999
+
2000
+ private class ImageDataLoaderStreamProviderWrapper extends ImageFromImageDataProviderWrapper {
2001
+ private byte [] inputStreamData ;
2002
+
2003
+ ImageDataLoaderStreamProviderWrapper (InputStream inputStream ) {
2004
+ try {
2005
+ this .inputStreamData = inputStream .readAllBytes ();
2006
+ } catch (IOException e ) {
2007
+ SWT .error (SWT .ERROR_INVALID_ARGUMENT , e );
2008
+ }
2009
+ }
2010
+
2011
+ private ImageDataLoaderStreamProviderWrapper (byte [] inputStreamData ) {
2012
+ this .inputStreamData = inputStreamData ;
2013
+ }
2014
+
2015
+ @ Override
2016
+ protected ElementAtZoom <ImageData > loadImageData (int zoom ) {
2017
+ return ImageDataLoader .load (new ByteArrayInputStream (inputStreamData ), FileFormat .DEFAULT_ZOOM , zoom );
2018
+ }
2019
+
2020
+ @ Override
2021
+ protected Rectangle getBounds (int zoom ) {
2022
+ ImageData scaledImageData = getImageData (zoom );
2023
+ return new Rectangle (0 , 0 , scaledImageData .width , scaledImageData .height );
2024
+ }
2025
+
2026
+ @ Override
2027
+ AbstractImageProviderWrapper createCopy (Image image ) {
2028
+ return new ImageDataLoaderStreamProviderWrapper (inputStreamData );
2029
+ }
2030
+ }
2031
+
2032
+ private class ImageDataLoaderFileProviderWrapper extends ImageFromImageDataProviderWrapper {
2033
+ private String fileName ;
2034
+
2035
+ ImageDataLoaderFileProviderWrapper (String fileName ) {
2036
+ this .fileName = fileName ;
2037
+ }
2038
+
2039
+ @ Override
2040
+ protected ElementAtZoom <ImageData > loadImageData (int zoom ) {
2041
+ return ImageDataLoader .load (fileName , FileFormat .DEFAULT_ZOOM , zoom );
2042
+ }
2043
+
2044
+ @ Override
2045
+ protected Rectangle getBounds (int zoom ) {
2046
+ ImageData scaledImageData = getImageData (zoom );
2047
+ return new Rectangle (0 , 0 , scaledImageData .width , scaledImageData .height );
2048
+ }
2049
+
2050
+ @ Override
2051
+ AbstractImageProviderWrapper createCopy (Image image ) {
2052
+ return new ImageDataLoaderFileProviderWrapper (fileName );
2053
+ }
2054
+ }
2055
+
1892
2056
private class PlainImageProviderWrapper extends AbstractImageProviderWrapper {
1893
2057
private boolean isDestroyed ;
1894
2058
private final int width ;
0 commit comments